ssm学习笔记day05

今天学习的是Restful实战

Dao层的完成

通过前面的学习,我们知道Dao 是直接面向数据库的,所以我们配好数据库环境。
创建一个名为restful_crud的数据库

sql 复制代码
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '员工名字',
  `age` int NULL DEFAULT NULL COMMENT '年龄',
  `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邮箱',
  `gender` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '性别',
  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '住址',
  `salary` decimal(10, 2) NULL DEFAULT NULL COMMENT '薪资',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of employee
-- ----------------------------
INSERT INTO `employee` VALUES (1, '张三', 11, 'aa@qq.com', '男', '西安', 9999.00);
INSERT INTO `employee` VALUES (4, 'leifengyang', 10, 'aaa', '男', 'sss', 100.00);

SET FOREIGN_KEY_CHECKS = 1;

然后在application.properities配置数据库信息

bash 复制代码
spring.application.name=springmvc-restful-crud
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/restful_crud
spring.datasource.username=root
spring.datasource.password=123456

Employee

java 复制代码
package com.atguigu.rest.crud.bean;

import lombok.Data;

import java.math.BigDecimal;


public class Employee {
    private Long id;
    private String name;
    private Integer age;
    private String email;
    private String gender;
    private String address;
    private BigDecimal salary;

    @Override
    public String toString() {
        return "Employee{" +
                "address='" + address + '\'' +
                ", id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                ", salary=" + salary +
                '}';
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getSalary() {
        return salary;
    }

    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }
}

在controller文件夹下创建EmployeeDao接口

bash 复制代码
package com.atguigu.rest.crud.dao;

import com.atguigu.rest.crud.bean.Employee;

public interface EmployeeDao {
    Employee getEmployeeById(Long id);
    void addEmployee(Employee employee);
    void updateEmployee(Employee employee);
    void deleteEmployee(Long id);
}

在controller/impl创建EmployeeDaoImpl实现类


需要补充的点

BeanPropertyRowMapper 是 Spring JDBC 框架中的一个实用类,用于将数据库查询结果集(ResultSet)自动映射到 Java Bean 对象。它通过反射机制,根据列名与 Bean 属性名的匹配关系进行自动映射,大大简化了手动从结果集提取数据并赋值给对象的过程。

bash 复制代码
package com.atguigu.rest.crud.dao.impl;

import com.atguigu.rest.crud.bean.Employee;
import com.atguigu.rest.crud.dao.EmployeeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class EmployeeDaoImpl implements EmployeeDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public Employee getEmployeeById(Long id) {
        String sql = "select * from employee where id = ?";
        Employee employee = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Employee.class), id);
        return employee;
    }

    @Override
    public void addEmployee(Employee employee) {
        String sql = "insert into employee (name, age , email,gender,address,salary) values (?, ? , ? , ? , ? , ?)";
        int update = jdbcTemplate.update(sql
                , employee.getName()
                , employee.getAge()
                , employee.getEmail()
                , employee.getGender()
                , employee.getAddress()
                , employee.getSalary());
        System.out.println("新增成功,影响行数" + update);

    }

    @Override
    public void updateEmployee(Employee employee) {
        String sql = "update employee set name=?,age=?,email=?,gender=?,address=?,salary=? where id = ?";
        int update = jdbcTemplate.update(sql , employee.getName()
                , employee.getAge()
                , employee.getEmail()
                , employee.getGender()
                , employee.getAddress()
                , employee.getSalary()
                , employee.getId());
        System.out.println("新增成功,影响行数" + update);
    }

    @Override
    public void deleteEmployee(Long id) {
        String sql = "delete from employee where id = ?";
        int update = jdbcTemplate.update(sql, id);
    }
}

Service层的完成

需要注意到的一点就是,Dao层的update操作中,如果某些参数为空的时候,会出现修改后仍为空的情况,作为controller直接调用的层,可以对数据做预处理。
代码


/service/impl/EmployeeService

java 复制代码
package com.atguigu.rest.crud.service;

import com.atguigu.rest.crud.bean.Employee;

public interface EmployeeService {

    Employee getEmp(Long id);

    void updateEmp(Employee employee);

    void addEmp(Employee employee);

    void deleteEmp(Long id);
}

/service/impl/EmployeeServiceImpl

StringUtils可以判断 字符是否非空非空白,如果是,则返回true

java 复制代码
package com.atguigu.rest.crud.service.impl;

import ch.qos.logback.core.util.StringUtil;
import com.atguigu.rest.crud.bean.Employee;
import com.atguigu.rest.crud.dao.EmployeeDao;
import com.atguigu.rest.crud.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service //controller 调用 service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeDao employeeDao;//静态代理

    @Override
    public Employee getEmp(Long id) {
        Employee empById = employeeDao.getEmployeeById(id);
        return null;
    }

    @Override
    public void updateEmp(Employee employee) {
        //防null 处理。考虑到service是被controller调用的
        //controller层传过来的employee的某些属性可能为null,所以先处理一下
        // 先查一下找原始数据
        // 把页面带来的数据覆盖原有的值
        Long id = employee.getId();
        if(id == null) return ;//没有带id
        System.out.println(id);
        Employee empById = employeeDao.getEmployeeById(id);
        //StringUtils可以判断 字符是否非空非空白
        if(!StringUtils.hasText(employee.getAddress())){
            empById.setAddress(employee.getAddress());
        }
        if(!StringUtils.hasText(employee.getName())){
            empById.setName(employee.getName());
        }
        if(!StringUtils.hasText(employee.getGender())){
            empById.setGender(employee.getGender());
        }
        if(!StringUtils.hasText(employee.getEmail())){
            empById.setEmail(employee.getEmail());
        }
        if(!StringUtils.hasText(employee.getName())){
            empById.setName(employee.getName());
        }
        if(employee.getSalary() != null){
            empById.setSalary(employee.getSalary());
        }
        if(employee.getAge() != null){
            empById.setAge(employee.getAge());
        }
        employeeDao.updateEmployee(employee);

    }

    @Override
    public void addEmp(Employee employee) {
        employeeDao.addEmployee(employee);
    }

    @Override
    public void deleteEmp(Long id) {
        employeeDao.deleteEmployee(id);
    }
}

Controller层的完成

设计目标

路径变量 PathVariable

我们可以在路径上定义一个动态变量接收一个参数,比如"/employee/{id}"

get方法的编写如下,相对于之前学习的@RequestParam,这里用到了@PathVariable去接收路径上的参数信息。

java 复制代码
package com.atguigu.rest.crud.controller;

import com.atguigu.rest.crud.bean.Employee;
import com.atguigu.rest.crud.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class EmployeeRestController {
    @Autowired
    private EmployeeService employeeService;

    @RequestMapping("/employee/{id}")//路径变量,动态的,{id}可以随机取值
    public Employee get(@PathVariable Long id) {//PathVariable路径变量,因为路径是动态的
        Employee employee = employeeService.getEmp(id);
        System.out.println(employee);
        return employee;
    }
}

crud的实现全代码

bash 复制代码
package com.atguigu.rest.crud.controller;

import com.atguigu.rest.crud.bean.Employee;
import com.atguigu.rest.crud.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class EmployeeRestController {
    @Autowired
    private EmployeeService employeeService;

    @RequestMapping(value = "/employee/{id}" , method = RequestMethod.GET)//路径变量,动态的,{id}可以随机取值
    public Employee get(@PathVariable Long id) {//PathVariable路径变量,因为路径是动态的
        Employee employee = employeeService.getEmp(id);
        System.out.println(employee);
        return employee;
    }

    @RequestMapping(value = "/employee/{id}" , method = RequestMethod.DELETE)//路径变量,动态的,{id}可以随机取值
    public String delete(@PathVariable("id") Long id) {//PathVariable路径变量,因为路径是动态的
        employeeService.deleteEmp(id);
        return "ok";
    }

    @PostMapping("/employee")
    public String add(@RequestBody Employee employee) {
        employeeService.addEmp(employee);
        return "ok";
    }

    @PutMapping("/employee")
    public String update(@RequestBody Employee employee) {//必须携带id
        employeeService.updateEmp(employee);
        return "ok";
    }
}

崩溃ing,找错误找半天,最终才发现是因为定义R类的时候没加getter方法,是因为我在用@Data的时候,总是爆神秘错误,然后我就手动getter and setter了,但是没加getter,可能是因为没getter获取不到里面的数据吧,然后就无法转换成功,呜呜呜。

不过查询相关资料,好像有个神秘的解决该错误的方法
神秘方法,然后用这个方法确实成功解决了问题。

在pom.xml注释掉该段,加上刷新一下maven即可。

class类R的编写

java 复制代码
package com.atguigu.rest.crud.common;

import lombok.Data;

@Data
public class R<T> {
    private Integer code;
    private String msg;
    private T data;

    public static <T> R<T> ok(T data) {
        R<T> r = new R<>();
        r.setCode(200);
        r.setMsg("ok");
        r.setData(data);
        return r;
    }
    public static <T> R<T> ok() {
        R<T> r = new R<>();
        r.setCode(200);
        r.setMsg("ok");
        return r;
    }
}

查询所有员工的实现

EmployeeImpl的实现,用的是query接口

java 复制代码
    @Override
    public List<Employee> getList() {
        String sql = "select * from employee";
        List<Employee> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Employee.class));

        return list;
    }
相关推荐
金心靖晨12 分钟前
笔记-极客-DDD实战-基于DDD的微服务拆分与设计
java·笔记·微服务
超浪的晨1 小时前
Java 内部类详解:从基础到实战,掌握嵌套类、匿名类与局部类的使用技巧
java·开发语言·后端·学习·个人开发
DKPT2 小时前
Java设计模式之行为型模式(命令模式)介绍与说明
java·笔记·学习·设计模式
yingtianhaoxuan3 小时前
学习笔记-Excel统计分析——描述统计量的计算
笔记·学习
MUTA️4 小时前
《Llama: The Llama 3 Herd of Models》预训练数据篇——论文精读笔记
人工智能·笔记·深度学习
andyguo4 小时前
语音识别的速度革命:从 Whisper 到 Whisper-CTranslate2,我经历了什么?
人工智能·学习·ai·whisper·语音识别·xcode·ai测评
fengye2071615 小时前
板凳-------Mysql cookbook学习 (十一--------9)
android·学习·mysql
麟城Lincoln6 小时前
【Linux-云原生-笔记】Apache相关
linux·笔记·云原生·apache·webserver
wu27906 小时前
MYSQL笔记2
数据库·笔记·mysql