SpringBoot基础之花式使用MybatisPlus

这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

前言

Mybatis像汽车,但是加持了MybatisPlus绝对是绝对是加装了氮气的超跑.

在没有使用MybatisPlus之前,在查询单表的时候要不默默的写sql代码,要不用代码生成器生成基础的代码,一旦参数有多种匹配方式,那么要不copy一份重写,要不加一个if条件,还是比较难受的.

但是一旦用了MybatisPlus 那仿佛是另一个世界.

MybatisPlus集成项目请看SpringBoot基础之集成MybatisPlus

前置基础信息

SQL

1
2
3
4
5
6
7
8
9
10
less复制代码CREATE TABLE `student` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`info` varchar(255) COMMENT 'zouzdc',
`del_flag` tinyint(1) DEFAULT '0',
`create_time` datetime,
`create_by` varchar(255),
`update_time` datetime ,
`update_by` varchar(255),
PRIMARY KEY (`id`)
) ;

Bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
ruby复制代码@Data
@NoArgsConstructor
public class Student {

/**
* id
*/
@TableId
private Long id;

/**
* 其他信息
*/
private String info;

/**
* 是否伪删除 0否 1是
*/
@TableLogic
private String delFlag;

/**
* 创建日期
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;

/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
private String createBy;

/**
* 更新日期
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

/**
* 更新人
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
}

MyBatisPlus增强配置-字段自动填充

正常来说,createTimecreateBydel_flag和租户等信息在输入插入的时候就需要赋值,而updateTimeupdateBy在数据变动的时候就需要重新赋值,对于这种模式固定的字段,可以使用MyBatisPlus的字段自动填充功能,让程序自动帮助我们做.

需要变动的位置,添加一个配置类,需要在Bean上需要的字段上添加注解

需要填充的字段上加注解@TableField(

例子如上图的Student

@TableField(fill = FieldFill.INSERT) 在新增会自动填充该字段,如果字段有值,则不会覆盖

@TableField(fill = FieldFill.INSERT_UPDATE) 在新增和更新都会自动填充该字段,如果字段有值则会覆盖

@TableField(fill = FieldFill.UPDATE) 在更新会自动填充该字段,如果字段有值则会覆盖

字段自动填充配置类

在配置类中,自定义配置每一个需要自动填充数据的字段的填充规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
typescript复制代码@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

@Override
public void insertFill(MetaObject metaObject) {

this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
this.strictInsertFill(metaObject, "createBy", String.class, getUserBy());
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
this.strictInsertFill(metaObject, "updateBy", String.class, getUserBy());
// 另一种方式 通用填充功能
//this.setFieldValByName("createTime",new Date(),metaObject);

}

@Override
public void updateFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
this.strictInsertFill(metaObject, "updateBy", String.class, getUserBy());
}

private String getUserBy(){
//获取当前操作人的方法,根据自己业务操作
return "admin";
}
}

数据逻辑删除

业务系统中大部分表不会真正的删除,所以需要使用某一个字段,定义是否伪删除. 只有调用MybatisPlus自带的方法且定义了删除字段的才会伪删除,否则会真删除.对于自己写的sql需要自行处理.

此处使用del_flag来定义是否伪删除,0是没有删除1是删除

application.yml

1
2
3
4
5
6
yaml复制代码mybatis-plus:
global-config:
db-config:
logic-delete-field: delFlag # 全局逻辑删除的实体字段名
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

Bean类上

1
2
3
4
5
arduino复制代码/**
* 是否伪删除 0否 1是
*/
@TableLogic
private String delFlag;

官网介绍自从3.3.0开始,在application.yml中配置了全局后, 可以不用再Bean上的字段配置@TableLogic

单表增删改查使用

controller层使用增删改查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
less复制代码@RestController
@RequestMapping("/student")
public class StudentController {

@Autowired(required = false)
public StudentService studentService;

@GetMapping("getById")
public R getStudentById( Student student){
//增
studentService.save(student);
//改
studentService.updateById(student);
//查
Student student = studentService.getById(student.getId());
//删
studentService.removeById(student.getId());
//列表 带参数查询
List<Student> zouzdc = studentService.lambdaQuery().eq(Student::getInfo, "zouzdc").list();
return R.success();
}
}

service层使用增删改查

增删改查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
less复制代码@Service
@Slf4j
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

@Autowired(required = false)
private StudentMapper studentMapper;


@Override
public void savePlus(Student student) {
//增
studentMapper.insert(student);
//改
studentMapper.updateById(student);
//查
baseMapper.selectById(student.getId());
//删
baseMapper.deleteById(student.getId());
//列表 带参数查询
List<Student> list = this.lambdaQuery().eq(Student::getId, student.getId()).list();
}
}

Service中自带默认的Mapper对象即baseMapper,等同于这里的studentMapper

单表条件查询示例

lambda语法

查询info等于zouzdc的list

1
perl复制代码 List<Student> zouzdc = studentService.lambdaQuery().eq(Student::getInfo, "zouzdc").list();

查询info等于zouzdc的一个对象

1
2
ini复制代码Student zouzdc = studentService.lambdaQuery().eq(Student::getInfo, "zouzdc").one();
Student zouzdc = studentService.lambdaQuery().eq(Student::getInfo, "zouzdc").last(" limit 1").one();

对于非唯一数据,直接使用one(),可能会出现非一条数据报错,可以使用last()拼接参数获取第一条数据

更新id=1info字段

1
perl复制代码 studentService.lambdaUpdate().set(Student::getInfo,"zdc").eq(Student::getId,1).update();

删除info是’zouzdc’的数据

1
csharp复制代码studentService.lambdaUpdate().set(Student::getInfo,"zouzdc").remove()

更多的条件构造请参看官方文档条件构造器一节

变种语法 不建议使用
1
2
perl复制代码 List<Student> zouzdc1 = studentService.list(new QueryWrapper<Student>().lambda().eq(Student::getInfo, "zouzdc"));
Student zouzdc2 = studentService.getOne(new LambdaQueryWrapper<Student>().eq(Student::getInfo, "zouzdc"));

分页查询

分页配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
less复制代码@Configuration
@MapperScan("zdc.enterprise.mapper.*")
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置最大单页限制数量,,-1 不受限制
paginationInterceptor.setLimit(1000);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}

lambda模式分页

1
2
3
4
5
6
7
8
perl复制代码
public IPage<StudentDto> listPage(StudentDto vo){

return this.lambdaQuery()
.eq(vo.getInfo() != null, Student::getInfo, vo.getInfo())
.eq(Student::getDelFlag, "0")
.page(new Page(vo.getCurrent(), vo.getSize()));
}

混合模式分页

Service层

1
2
3
4
5
6
7
8
9
10
11
scss复制代码 public  Page<StudentDto> listPage(StudentDto vo){

Page<Student> page = new Page(vo.getCurrent(), vo.getSize());
page.addOrder(OrderItem.desc("a.create_time"));

QueryWrapper<Student> wrapper = new QueryWrapper();
wrapper.apply(" a.del_flag =0 ");
wrapper.eq("a.info","zouzdc")
.le("a.id",10);
return baseMapper.listPage(page, wrapper);
}

Mapper层

1
less复制代码Page<StudentDto> listPage(@Param("page") Page<Student> page, @Param("ew") QueryWrapper<Student> wrapper);

@Param("ew")是固定的默认的

XML层

1
2
3
4
5
csharp复制代码<select id="listPage" resultType="zdc.enterprise.dto.StudentDto">
select * from student a
${ew.customSqlSegment}

</select>

这种写法是在service层写sql形式的where条件,然后通过${ew.customSqlSegment}拼接到xml中sql的后面.会自带where

还有更多写法…自己研究吧

1
2
3
4
arduino复制代码作者:ZOUZDC
链接:https://juejin.cn/post/7028963866063306760
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%