MybatisPlus的增删改查

212 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

1.准备工作

介绍:本篇文章主要内容是介绍mybatisplus的基础操作,具体内容如下:

  1. 查询所有
  2. 逻辑删除
  3. 按条件分页查询
  4. 添加
  5. 修改
  6. 批量删除

数据库表介绍:

image.png 实体类介绍(因为我没用postman来测试数据,我是用swagger来测试数据,所以实体类里面会有一些注解,不需要swagger的同学可以忽略这些注解):

@Data
@ApiModel(description = "Teacher")
@TableName("teacher")
public class Teacher extends BaseEntity {

   private static final long serialVersionUID = 1L;

   @ApiModelProperty(value = "讲师姓名")
   @TableField("name")
   private String name;

   @ApiModelProperty(value = "讲师简介")
   @TableField("intro")
   private String intro;

   @ApiModelProperty(value = "讲师资历,一句话说明讲师")
   @TableField("career")
   private String career;

   @ApiModelProperty(value = "头衔 1高级讲师 2首席讲师")
   @TableField("level")
   private Integer level;

   @ApiModelProperty(value = "讲师头像")
   @TableField("avatar")
   private String avatar;

   @ApiModelProperty(value = "排序")
   @TableField("sort")
   private Integer sort;

   @ApiModelProperty(value = "入驻时间")
   @JsonFormat(pattern = "yyyy-MM-dd")
   @TableField("join_date")
   private Date joinDate;

}

配置文件介绍:

# 服务端口
server.port=8301
# 服务名
spring.application.name=service-vod

# 环境设置:dev、test、prod
spring.profiles.active=dev

# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/glkt_vod?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456

#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

关键依赖介绍:

<!--mybatis-plus 持久层-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybatis-plus.version}</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.version}</version>
</dependency>

1.1 创建mapper

我们创建一个mapper,这个mapper继承BaseMapper。注意:泛型的内容是对应的实体类,比如:我们操作的是教室表,我们就将Teacher类放到这里的泛型,具体的Teacher大家可以参考上面的实体类。

public interface TeacherMapper extends BaseMapper<Teacher> {

}

1.2 创建service

我们创建一个service接口,这个接口继承IService。同样的,泛型的内容是对应的实体类

public interface TeacherService extends IService<Teacher> {

}

1.3 创建service接口的实现类

我们创建的service接口的实现类时,先让这个接口去继承ServiceImpl<M, T>,因为ServiceImpl里面有很多已经实现了的方法,后面我们还要实现我们刚刚创建的service接口。如果不继承ServiceImpl,我们继承我们刚刚创建的service接口的时候需要自己实现很多方法。

@Service
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> implements TeacherService {

}

至此,我们的准备工作到此结束。如果对mabatisplus有一定了解的同学,可能会想到这个框架给我们提供了代码生成器,大家可以用这个生成器来生成代码,不必自己手动来写。

2.查询所有

@ApiOperation是swagger的注解,如果对swagger不了解的同学可以忽略它。list方法是mybatisplus的service接口带来的方法,作用是可以查询所有数据。Result是我统一的数据格式,大家可以根据自己的喜好来。

@Autowired
private TeacherService teacherService;
    
//1.查询所有讲师
@ApiOperation("查询所有讲师")
@GetMapping("findAll")
public Result findAllTeacher(){
    //调用service方法
    List<Teacher> list = teacherService.list();
    return Result.ok(list).message("查询数据成功");
}

3.逻辑删除

@ApiParam也是swagger里面的注解,大家可以忽略它。removeById是mybatisplus的service接口带来的方法,作用是可以根据id删除数据。

@ApiOperation("逻辑删除讲师")
@DeleteMapping("remove/{id}")
public Result removeTeacher(@ApiParam(name = "id", value = "ID", required = true)
                                 @PathVariable Long id){
    boolean isSuccess = teacherService.removeById(id);
    if (isSuccess){
        return Result.ok(null);
    }else {
        return Result.fail(null);
    }

}

4.按条件分页查询

大家注意下,这个接口请求方式是post。为什么采用这个格式的原因是,我们希望这个接口不仅能分页查询所有数据,也希望它能按条件分页查询数据,所以我们需要在这个接口写上查询页面,每页显示条数和查询条件。我们将查询条件放在了一个TeacherQueryVo类里面,这个类用@RequestBody(required = false)标注,里面的值是false是因为用户可以选择不带任何查询条件,而且因为用了@RequestBody,所以就不采用get方式来获取数据了。

mybatisplus的分页查询功能需要我们自己配置,我们可以写一个配置类,这个类如下:

@Configuration
@MapperScan("com.atguigu.ggkt.vod.mapper")
public class VodConfig {

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

}

TeacherQueryVo类

@Data
public class TeacherQueryVo {
   
   @ApiModelProperty(value = "讲师姓名")
   private String name;

   @ApiModelProperty(value = "头衔 1高级讲师 2首席讲师")
   private Integer level;

   @ApiModelProperty(value = "入驻时间")
   private String joinDateBegin;

   @ApiModelProperty(value = "入驻时间")
   private String joinDateEnd;


}

接口:

@ApiOperation("条件查询分页")
@PostMapping("findQueryPage/{current}/{limit}")
public Result findPage(@PathVariable long current,
                       @PathVariable long limit,
                       @RequestBody(required = false) TeacherQueryVo teacherQueryVo) {
    //创建page对象
    Page<Teacher> pageParam = new Page<>(current,limit);
    //判断teacherQueryVo对象是否为空
    if (teacherQueryVo == null){//查询全部
        IPage<Teacher> pageModel = teacherService.page(pageParam,null);
        return Result.ok(pageModel);
    }else {
        //获取条件值,
        String name = teacherQueryVo.getName();
        Integer level = teacherQueryVo.getLevel();
        String joinDateBegin = teacherQueryVo.getJoinDateBegin();
        String joinDateEnd = teacherQueryVo.getJoinDateEnd();

        //进行非空判断,条件封装
        QueryWrapper<Teacher> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(name)){
            wrapper.like("name",name);
        }
        if (!StringUtils.isEmpty(level)){
            wrapper.eq("level",level);
        }
        if (!StringUtils.isEmpty(joinDateBegin)){
            wrapper.ge("join_date",joinDateBegin);
        }
        if (!StringUtils.isEmpty(joinDateEnd)){
            wrapper.le("join_date",joinDateEnd);
        }

        //调用方法分页查询

        IPage<Teacher> pageModel = teacherService.page(pageParam, wrapper);
        //返回
        return Result.ok(pageModel);
    }
}

从接口的实现中,我们发现Page对象保存了我们查询到我们分页后的数据。我们这个接口有一个判断,就是判断用户有没有传递查询条件。如果没有传递查询条件,service接口直接调用page方法,第一个参数写上生成的page对象,另一个参数写个null;如果有传递查询条件,service接口直接调用page方法,第一个参数写上生成的page对象,另一个参数写上QueryWrapper对象,QueryWrapper对象封装了查询条件。

注意:StringUtils.isEmpty是spring框架自带的判断字符串是否非空的方法。

5.添加

添加方法相对来说比较简单,只需调用service接口的save方法即可,参数写上实体类就行。

@ApiOperation("添加讲师")
@PostMapping("saveTeacher")
public Result saveTeacher(@RequestBody Teacher teacher) {
    boolean isSuccess = teacherService.save(teacher);
    if (isSuccess) {
        return Result.ok(null);
    }else {
        return Result.fail(null);
    }
}

6.修改

我们的修改写成了两个接口,第一个接口是根据id查询数据,第二个接口是根据id修改数据。有同学可能会有疑问,为什么要写两个接口呢?大家想一下,修改数据的时候是不是需要回显,让用户看到你要修改的数据,这就是为什么要写一个根据id查询的接口的原因。

6.1 根据id查询

service接口的getById方法作用就是根据id来查询数据。

@ApiOperation("根据id查询")
@GetMapping("getTeacher/{id}")
public Result getTeacher(@PathVariable Long id) {
    Teacher teacher = teacherService.getById(id);
    return Result.ok(teacher);
}

6.2 根据id修改

service接口的updateById方法就是来修改数据的,你传入需要修改的数据即可,这些数据可以封装在实体类里面,因为updateById方法的参数就是实体类。

@ApiOperation("修改最终实现")
@PostMapping("updateTeacher")
public Result updateTeacher(@RequestBody Teacher teacher) {
    boolean isSuccess = teacherService.updateById(teacher);
    if (isSuccess) {
        return Result.ok(null);
    }else {
        return Result.fail(null);
    }
}

7.批量删除

批量删除的时候可以调用service接口的removeByIds方法,这个方法的参数是Collection类型的。那大家应该可以猜到,我们这个接口的参数可以是一个List集合,用这个集合保存要删除的数据的id。其实我们发现list数据转换成json数据格式是[id1,id2,id3],前端同学也是发这样的[id1,id2,id3]json数据给我们的,从这个角度出发,我们个接口的参数可以是一个List集合。

@ApiOperation("批量删除讲师")
@DeleteMapping("removeBatch")
public Result removeBatch(@RequestBody List<Long> idList){
    boolean isSuccess = teacherService.removeByIds(idList);
    if (isSuccess) {
        return Result.ok(null);
    }else {
        return Result.fail(null);
    }
}

8.验证

用swagger方式来验证 这是我们的接口

image.png 里面的具体样式:

image.png 验证查询所有:

image.png 验证分页查询:

image.png

image.png 根据id查询:

image.png

image.png 逻辑删除:

image.png

image.png

批量删除:

image.png

image.png

添加:

image.png

image.png

修改:

image.png

image.png