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;
    }
相关推荐
Zhao-Jichao2 小时前
AI Prompting for Everyone 课程笔记 - P21 总结 Conclusion
人工智能·笔记
欢欢李2 小时前
【LTE L3 笔记 05】LTE同步信号
笔记·无线通信·物理层·lte·空口协议
La Pulga4 小时前
【FreeRTOS源码学习笔记】空闲任务与阻塞延时
笔记·mcu·学习·嵌入式·freertos·实时操作系统
蒸蒸yyyyzwd4 小时前
秋招学习笔记 day106
笔记·学习
小李不想当小白5 小时前
WDG看门狗(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
欢欢李6 小时前
【LTE L3 笔记 04】LTE帧结构
笔记·无线通信·物理层·lte·空口协议
Zhao-Jichao8 小时前
AI Prompting for Everyone 课程笔记 - P20 实验与期末项目 Lab and Final Project
前端·人工智能·笔记
lisw059 小时前
作为人类代理的大语言模型及其角色分类!
人工智能·学习·语言模型
Z21-X9 小时前
云原生运维实战笔记:企业网站综合上云部署与云运维服务全景解析
运维·笔记·学习·云原生
坤坤子吖9 小时前
Linux网络编程:UDP进阶,从字典服务器到简单聊天室
linux·服务器·网络·c++·笔记·学习