SpringBootWeb增删改查入门案例

news/2024/9/19 0:13:19 标签: springboot, mybatis, 增删改查, 案例, 入门

前言

为了快速入门一个SpringBootWeb项目,这里就将基础的增删改查案例进行总结,作为对SpringBoot+Mybatis的基础用法的一个巩固。

准备工作

  1. 需求说明
    对员工表进行增删改查操作
  2. 环境搭建
  • 准备数据表
-- 员工管理(带约束)
create table emp (
  id int unsigned primary key auto_increment comment 'ID',
  username varchar(20) not null unique comment '用户名',
  password varchar(32) default '123456' comment '密码',
  name varchar(10) not null comment '姓名',
  gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',
  image varchar(300) comment '图像',
  job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',
  entrydate date comment '入职时间',
  dept_id int unsigned comment '部门ID',
  create_time datetime not null comment '创建时间',
  update_time datetime not null comment '修改时间'
) comment '员工表';
-- 员工表测试数据
INSERT INTO emp
    (id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES
    (1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),
    (2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),
    (3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),
    (4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),
    (5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),
    (6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),
    (7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),
    (8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),
    (9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),
    (10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),
    (11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,now(),now()),
    (12,'hebiweng','123456','鹤笔翁',1,'12.jpg',5,'2008-08-18',3,now(),now()),
    (13,'fangdongbai','123456','方东白',1,'13.jpg',5,'2012-11-01',3,now(),now()),
    (14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),
    (15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),
    (16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2007-01-01',2,now(),now()),
    (17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());
  • 创建springboot工程,引入对应的起步依赖(web、mybatis、mysql驱动、lombok)
    在这里插入图片描述

  • 配置文件application.properties中引入mybatis的配置信息,准备对应的实体类

    • application.properties
      #数据库连接
      spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
      spring.datasource.url=jdbc:mysql://localhost:3306/tlias
      spring.datasource.username=root
      spring.datasource.password=1234
      
      #开启mybatis的日志输出
      mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
      
      #开启数据库表字段 到 实体类属性的驼峰映射
      mybatis.configuration.map-underscore-to-camel-case=true
      
    • 实体类
      /*员工类*/
      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      public class Emp {
          private Integer id;
          private String username;
          private String password;
          private String name;
          private Short gender;
          private String image;
          private Short job;
          private LocalDate entrydate;
          private Integer deptId;
          private LocalDateTime createTime;
          private LocalDateTime updateTime;
      }
      
  • 准备对应的Mapper、Service(接口、实现类)、Controller基础结构

    数据访问层:

    • EmpMapper
      import org.apache.ibatis.annotations.Mapper;
      
      @Mapper
      public interface EmpMapper {
      }
      

    业务层:

    • EmpService

      //员工业务规则
      public interface EmpService {
      }
      
    • EmpServiceImpl

      import com.exmaple.service.EmpService;
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.stereotype.Service;
      
      //员工业务实现类
      @Slf4j
      @Service
      public class EmpServiceImpl implements EmpService {
      
      }
      

    控制层:

    • EmpController
      package com.exmple.controller;
      import org.springframework.web.bind.annotation.RestController;
      
      //员工管理控制器
      @RestController
      public class EmpController {
      }
      
  1. 开发规范
  • REST

    • 传统URL和REST风格比较
      (1)传统URL风格

      http://localhost:8080/user/getById?id=1     GET:查询id为1的用户
      http://localhost:8080/user/saveUser         POST:新增用户
      http://localhost:8080/user/updateUser       POST:修改用户
      http://localhost:8080/user/deleteUser?id=1  GET:删除id为1的用户
      

      (2)REST风格URL:

      http://localhost:8080/users/1  GET:查询id为1的用户
      http://localhost:8080/users    POST:新增用户
      http://localhost:8080/users    PUT:修改用户
      http://localhost:8080/users/1  DELETE:删除id为1的用户
      

    其中总结起来,就一句话:通过URL定位要操作的资源,通过HTTP动词(请求方式)来描述具体的操作。

    在REST风格的URL中,通过四种请求方式,来操作数据的增删改查

    • GET : 查询
    • POST :新增
    • PUT :修改
    • DELETE :删除
  • 统一响应结果

    前后端工程在进行交互时,使用统一响应结果 Result。

    package com.example.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Result {
        private Integer code;//响应码,1 代表成功; 0 代表失败
        private String msg;  //响应信息 描述字符串
        private Object data; //返回的数据
    
        //增删改 成功响应
        public static Result success(){
            return new Result(1,"success",null);
        }
        //查询 成功响应
        public static Result success(Object data){
            return new Result(1,"success",data);
        }
        //失败响应
        public static Result error(String msg){
            return new Result(0,msg,null);
        }
    }
    
  1. 开发流程
  • 查看页面原型明确需求

    • 根据页面原型和需求,进行表结构设计、编写接口文档(已提供)
  • 阅读接口文档

  • 思路分析

  • 功能接口开发

    • 就是开发后台的业务功能,一个业务功能,我们称为一个接口
  • 功能接口测试

    • 功能开发完毕后,先通过Postman进行功能接口测试,测试通过后,再和前端进行联调测试
  • 前后端联调测试

    • 和前端开发人员开发好的前端工程一起测试

新增员工

  1. 需求
    在新增用户时,我们需要保存用户的基本信息,并且还需要上传的员工的图片,目前我们先完成第一步操作,保存用户的基本信息。

  2. 接口文档

我们参照接口文档来开发新增员工功能

  • 基本信息
请求路径:/emps

请求方式:POST

接口描述:该接口用于添加员工的信息
  • 请求参数
    参数格式:application/json

    参数说明:

    名称类型是否必须备注
    usernamestring必须用户名
    namestring必须姓名
    gendernumber必须性别, 说明: 1 男, 2 女
    imagestring非必须图像
    deptIdnumber非必须部门id
    entrydatestring非必须入职日期
    jobnumber非必须职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师

    请求数据样例:

    {
      "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-03-07-37-38222.jpg",
      "username": "linpingzhi",
      "name": "林平之",
      "gender": 1,
      "job": 1,
      "entrydate": "2022-09-18",
      "deptId": 1
    }
    
  • 响应数据

    参数格式:application/json

    参数说明:

    参数名类型是否必须备注
    codenumber必须响应码,1 代表成功,0 代表失败
    msgstring非必须提示信息
    dataobject非必须返回的数据
  1. 思路分析
    接口文档规定:

    • 请求路径:/emps
    • 请求方式:POST
    • 请求参数:Json格式数据
    • 响应数据:Json格式数据

    问题1:如何限定请求方式是POST?

    @PostMapping
    

    问题2:怎么在controller中接收json格式的请求参数?

    @RequestBody  //把前端传递的json数据填充到实体类中
    
  2. 功能开发
    EmpController

@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {

    @Autowired
    private EmpService empService;

    //新增
    @PostMapping
    public Result save(@RequestBody Emp emp){
        //记录日志
        log.info("新增员工, emp:{}",emp);
        //调用业务层新增功能
        empService.save(emp);
        //响应
        return Result.success();
    }

    //省略...
}

EmpService

public interface EmpService {

    /**
     * 保存员工信息
     * @param emp
     */
    void save(Emp emp);

    //省略...
}

EmpServiceImpl

@Slf4j
@Service
public class EmpServiceImpl implements EmpService {
    @Autowired
    private EmpMapper empMapper;

    @Override
    public void save(Emp emp) {
        //补全数据
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        //调用添加方法
        empMapper.insert(emp);
    }

    //省略...
}

EmpMapper

@Mapper
public interface EmpMapper {
    //新增员工
    @Insert("insert into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " +
            "values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime});")
    void insert(Emp emp);

    //省略...
}

删除员工

  1. 需求
    前端页面可以一次性删除一个或多个员工。
    问题:我们需要开发两个功能接口吗?一个删除单个员工,一个删除多个员工
    答案:不需要。 只需要开发一个功能接口即可(删除多个员工包含只删除一个员工)

  2. 接口文档

  • 基本信息

    请求路径:/emps/{ids}
    
    请求方式:DELETE
    
    接口描述:该接口用于批量删除员工的数据信息
    
  • 请求参数
    参数格式:路径参数

    参数说明:

    参数名类型示例是否必须备注
    ids数组 array1,2,3必须员工的id数组

    请求参数样例:

    /emps/1,2,3
    
  • 响应数据

    参数格式:application/json

    参数说明:

    参数名类型是否必须备注
    codenumber必须响应码,1 代表成功,0 代表失败
    msgstring非必须提示信息
    dataobject非必须返回的数据

    响应数据样例:

    {
        "code":1,
        "msg":"success",
        "data":null
    }
    
  1. 思路分析
    接口文档规定:
  • 前端请求路径:/emps/{ids}

  • 前端请求方式:DELETE

    问题1:怎么在controller中接收请求路径中的路径参数?

    @PathVariable
    

    问题2:如何限定请求方式是delete?

    @DeleteMapping
    

    问题3:在Mapper接口中,执行delete操作的SQL语句时,条件中的id值是不确定的是动态的,怎么实现呢?

    Mybatis中的动态SQL:foreach
    
  1. 功能开发
    EmpController

    @Slf4j
    @RestController
    @RequestMapping("/emps")
    public class EmpController {
    
        @Autowired
        private EmpService empService;
    
        //批量删除
        @DeleteMapping("/{ids}")
        public Result delete(@PathVariable List<Integer> ids){
            empService.delete(ids);
            return Result.success();
        }
    
    }
    

    EmpService

    public interface EmpService {
    
        /**
         * 批量删除操作
         * @param ids id集合
         */
        void delete(List<Integer> ids);
    
        //省略...
    }
    

    EmpServiceImpl

    @Slf4j
    @Service
    public class EmpServiceImpl implements EmpService {
        @Autowired
        private EmpMapper empMapper;
    
        @Override
        public void delete(List<Integer> ids) {
            empMapper.delete(ids);
        }
    
        //省略...
    }
    

    EmpMapper

    @Mapper
    public interface EmpMapper {
        //批量删除
        void delete(List<Integer> ids);
    
        //省略...
    }
    

    EmpMapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.example.mapper.EmpMapper">
    
        <!--批量删除员工-->
        <select id="delete">
            delete from emp where id in
            <foreach collection="ids" item="id" open="(" close=")" separator=",">
                #{id}
            </foreach>
        </select>
    
        <!-- 省略... -->
    
    </mapper>
    

    元素用于迭代传入的集合。在这个例子中,它用于构建IN子句中的值列表。
    collection属性:指定要迭代的集合名称。在这个例子中,collection="ids"意味着传入的参数应该是一个名为ids的集合。
    item属性:指定每次迭代时使用的变量名。在这里,item=“id"表示每次迭代时,当前元素会被赋值给变量id。
    open属性:指定循环产生的SQL片段的开头字符。在这里,open=”(“表示循环开始时添加一个左括号。
    close属性:指定循环产生的SQL片段的结尾字符。在这里,close=”)“表示循环结束时添加一个右括号。
    separator属性:指定每次迭代之间使用的分隔符。在这里,separator=”,"表示每次迭代之间添加一个逗号。

修改员工

  1. 需求
    修改员工信息

  2. 接口文档

    • 基本信息

      请求路径:/emps
      
      请求方式:PUT
      
      接口描述:该接口用于修改员工的数据信息
      
    • 请求参数

      参数格式:application/json

      参数说明:

      名称类型是否必须备注
      idnumber必须id
      usernamestring必须用户名
      namestring必须姓名
      gendernumber必须性别, 说明: 1 男, 2 女
      imagestring非必须图像
      deptIdnumber非必须部门id
      entrydatestring非必须入职日期
      jobnumber非必须职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师

      请求数据样例:

      {
        "id": 1,
        "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-03-07-37-38222.jpg",
        "username": "linpingzhi",
        "name": "林平之",
        "gender": 1,
        "job": 1,
        "entrydate": "2022-09-18",
        "deptId": 1
      }
      
    • 响应数据

      参数格式:application/json

      参数说明:

      参数名类型是否必须备注
      codenumber必须响应码,1 代表成功,0 代表失败
      msgstring非必须提示信息
      dataobject非必须返回的数据

      响应数据样例:

      {
          "code":1,
          "msg":"success",
          "data":null
      }
      
  3. 代码实现

  • EmpMapper

    @Mapper
    public interface EmpMapper {
        //修改员工信息
        public void update(Emp emp);
    
        //省略...
    }
    
    • EmpMapper.xml
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.itheima.mapper.EmpMapper">
    
        <!--更新员工信息-->
        <update id="update">
            update emp
            <set>
                <if test="username != null and username != ''">
                    username = #{username},
                </if>
                <if test="password != null and password != ''">
                    password = #{password},
                </if>
                <if test="name != null and name != ''">
                    name = #{name},
                </if>
                <if test="gender != null">
                    gender = #{gender},
                </if>
                <if test="image != null and image != ''">
                    image = #{image},
                </if>
                <if test="job != null">
                    job = #{job},
                </if>
                <if test="entrydate != null">
                    entrydate = #{entrydate},
                </if>
                <if test="deptId != null">
                    dept_id = #{deptId},
                </if>
                <if test="updateTime != null">
                    update_time = #{updateTime}
                </if>
            </set>
            where id = #{id}
        </update>
    
        <!-- 省略... -->
    
    </mapper>
    
    • EmpService
    public interface EmpService {
        /**
         * 更新员工
         * @param emp
         */
        public void update(Emp emp);
    
        //省略...
    }
    
    • EmpServiceImpl
    @Slf4j
    @Service
    public class EmpServiceImpl implements EmpService {
        @Autowired
        private EmpMapper empMapper;
    
        @Override
        public void update(Emp emp) {
            emp.setUpdateTime(LocalDateTime.now()); //更新修改时间为当前时间
    
            empMapper.update(emp);
        }
    
        //省略...
    }
    
    • EmpController
    @Slf4j
    @RestController
    @RequestMapping("/emps")
    public class EmpController {
    
        @Autowired
        private EmpService empService;
    
        //修改员工
        @PutMapping
        public Result update(@RequestBody Emp emp){
            empService.update(emp);
            return Result.success();
        }
    
        //省略...
    }
    

查询员工

  1. 需求
  • 根据ID查询员工信息
  1. 接口文档
    根据ID查询员工数据

    • 基本信息

      请求路径:/emps/{id}
      
      请求方式:GET
      
      接口描述:该接口用于根据主键ID查询员工的信息
      
    • 请求参数

      参数格式:路径参数

      参数说明:

      参数名类型是否必须备注
      idnumber必须员工ID

      请求参数样例:

      /emps/1
      
    • 响应数据

      参数格式:application/json

      参数说明:

      名称类型是否必须默认值备注
      codenumber必须响应码, 1 成功 , 0 失败
      msgstring非必须提示信息
      dataobject必须返回的数据
      idnumber非必须id
      usernamestring非必须用户名
      namestring非必须姓名
      passwordstring非必须密码
      entrydatestring非必须入职日期
      gendernumber非必须性别 , 1 男 ; 2 女
      imagestring非必须图像
      jobnumber非必须职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师
      deptIdnumber非必须部门id
      createTimestring非必须创建时间
      updateTimestring非必须更新时间

      响应数据样例:

      {
        "code": 1,
        "msg": "success",
        "data": {
          "id": 2,
          "username": "zhangwuji",
          "password": "123456",
          "name": "张无忌",
          "gender": 1,
          "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-02-00-27-53B.jpg",
          "job": 2,
          "entrydate": "2015-01-01",
          "deptId": 2,
          "createTime": "2022-09-01T23:06:30",
          "updateTime": "2022-09-02T00:29:04"
        }
      }
      
  2. 代码实现

  • EmpMapper

    @Mapper
    public interface EmpMapper {
    
        //根据ID查询员工信息
        @Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time " +
                "from emp " +
                "where id = #{id}")
        public Emp findById(Integer id);
    
    
        //省略...
    }
    
    • EmpService
    public interface EmpService {
    
        /**
         * 根据ID查询员工
         * @param id
         * @return
         */
        public Emp getById(Integer id);
    
        //省略...
    }
    
    • EmpServiceImpl
    @Slf4j
    @Service
    public class EmpServiceImpl implements EmpService {
        @Autowired
        private EmpMapper empMapper;
    
        @Override
        public Emp getById(Integer id) {
            return empMapper.findById(id);
        }
    
        //省略...
    }
    
    • EmpController
    @Slf4j
    @RestController
    @RequestMapping("/emps")
    public class EmpController {
    
        @Autowired
        private EmpService empService;
    
        //根据id查询
        @GetMapping("/{id}")
        public Result getById(@PathVariable Integer id){
            Emp emp = empService.getById(id);
            return Result.success(emp);
        }
    
        //省略...
    }
    

后记

springboot + mybatis做数据的增删改查其实相对比较简单,我们根据上面的案例就可以进行学习,主要关注的是常用的注解以及mybatis复杂查询时xml文件的配置。


http://www.niftyadmin.cn/n/5664752.html

相关文章

C++_类和对象(下篇)—— 内部类、匿名对象、对象拷贝时的编译器优化

目录 四、类和对象&#xff08;下篇&#xff09; 5、内部类 6、匿名对象 7、对象拷贝时的编译器优化 四、类和对象&#xff08;下篇&#xff09; 5、内部类 如果⼀个类定义在另⼀个类的内部&#xff0c;这个内部类就叫做内部类。内部类是⼀个独立的类&#xff0c;跟定义…

【CSS】样式水平垂直居中

行内元素&#xff1a; 如果被设置元素为文本、图片等行内元素时&#xff0c;水平居中是通过给父元素设置 text-align:center <body> <div class"txtCenter">我想要在父容器中水平居中显示。</div> </body>div是文本元素的父元素 因此我们对…

C/C++语言基础--C++面向对象、类、对象概念讲解

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 今天更新的比较晚了&#xff0c;主要一直用是谷歌Colab训练模型&#xff0c;访问国内csdn反而不好使了&#xff0c;请大家见谅&#xff1b;C是面向对象的语言&#xff0c;本文将介绍什么是面向对象、什么是类…

容器镜像同步工具image-migrator

1 概述 image-migrator是一个用于容器镜像同步的可执行二进制命令行工具&#xff08;不依赖于docker命令&#xff09;&#xff0c;能够自动将基于Docker Registry v2镜像仓库&#xff08;registry、云厂商容器镜像服务、docker hub、Quay、Harbor &#xff09;中的镜像迁移到基…

ShouldSniffAttr在自动化测试中具体是如何应用?

在自动化测试中&#xff0c;ShouldSniffAttr 这样的函数名通常暗示它是一个用于断言&#xff08;assertions&#xff09;的工具&#xff0c;用于检查某个元素或属性是否符合预期的条件。 虽然这不是一个标准的函数名&#xff0c;但我们可以根据命名推测其用途。 例如&#xf…

一种全新的webapi框架C#webmvc初步介绍

这个框架分三部分&#xff0c;第一部分数据结构层&#xff0c;第二部分http和业务管理以及sql层&#xff0c;第三部分加密层和工具类。 数据结构层分key和数据长度定义 public class Auth { [Key] public string Id { get; set; } [MaxLength(50)…

Ai+若依(智能售货机运营管理系统---帝可得)--货道关联商品【08篇---0004:关联商品】

货道关联商品 需求 对智能售货机内部的货道进行商品摆放的管理 此功能涉及四个后端接口 查询设备类型&#xff08;已完成&#xff09; 查询货道列表&#xff08;待完成&#xff09; 查询商品列表&#xff08;已完成&#xff09; 货道关联商品&#xff08;待完成&#xff0…

迈入IT世界:技术趋势、职业选择与未来展望

迈入IT世界&#xff1a;技术趋势、职业选择与未来展望 1. 引言 随着科技的飞速发展&#xff0c;信息技术&#xff08;IT&#xff09;已经成为当今社会的中坚力量。无论是智能设备、互联网服务&#xff0c;还是数据分析与人工智能&#xff0c;IT技术驱动着各行各业的创新与进步…