本篇基于MP 3.3.0 版本 ,spring boot 方式。
MyBatis-plus 简介:
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
支持数据库
-
mysql 、 mariadb 、 oracle 、 db2 、 h2 、 hsql 、 sqlite 、 postgresql 、 sqlserver
-
达梦数据库 、 虚谷数据库 、 人大金仓数据库
快速开始
- 建立数据库,导入数据
- 导入对应的依赖
- 编写项目
- 配置数据库连接
- 编写实体类
- 编写Mapper接口继承BaseMapper<T> 即可!至此所有CRUD都已完成
- 测试使用
详细看官网:https://mybatis.plus
插入策略
- 用户ID自动回填
- 主键生成策略
- 自增
- 手动输入
- UUID
- 雪花算法
- 唯一ID生成器
- 唯一ID生成器(字符串类型)
-
关于id生成的一些策略:https://www.cnblogs.com/haoxinyue/p/5208136.html

1 public enum IdType {
2 // 自增
3 AUTO(0),
4 NONE(1),
5 // 手动输入
6 INPUT(2),
7 // 唯一id生成器,默认策略
8 ID_WORKER(3),
9 // uuid
10 UUID(4),
11 // 唯一id生成器(字符串类型)
12 ID_WORKER_STR(5); }
更新策略
阿里巴巴规范中,id、gmt_create、gmr_update !

给数据库表增加两个字段测试
- 自动更新策略两种级别
- 数据库级别(不建议)
- 设置默认值
- 插入、更新测试
- 代码级别(建议)
- 删除更新默认值
- 编写实体类对应注解
- 编写注解的处理器
- 数据库级别(不建议)
数据库级别

代码级别
1 @TableField(fill = FieldFill.INSERT) 2 private Date insertTime; // 创建时间 3 @TableField(fill = FieldFill.INSERT_UPDATE) 4 private Date updateTime; // 更新时间
1 package com.coding.handler;
2
3 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
4 import org.apache.ibatis.reflection.MetaObject;
5 import org.springframework.stereotype.Component;
6
7 import java.util.Date;
8
9 @Component
10 public class MyMetaObjectHandler implements MetaObjectHandler {
11 /*
12 * default MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject) {
13 if (Objects.nonNull(fieldVal) && metaObject.hasSetter(fieldName)) {
14 metaObject.setValue(fieldName, fieldVal);
15 }
16 return this;
17 }*/
18 @Override
19 public void insertFill(MetaObject metaObject) {
20 this.setFieldValByName("insertTime",new Date(),metaObject);
21 this.setFieldValByName("updateTime",new Date(),metaObject);
22 }
23
24 @Override
25 public void updateFill(MetaObject metaObject) {
26 this.setFieldValByName("updateTime",new Date(),metaObject);
27 }
28 }
乐观锁
- 乐观锁:非常乐观,无论什么操作都不加锁!(思考:分布式环境下怎么解决冲突问题?)
- 悲观锁:非常悲观,无论什么操作都加锁!默认情况下都是悲观锁!
解决问题
通常方式就是增加一个乐观锁字段(version)
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前version (查询)old version = 1
- 更新时,带上这个version (更新)
- 执行更新时,set version = newVersion where version = old version
- 如果version不对应,就更新失败
- 对应,就更新成功
MP对乐观锁也进行了支持
- 添加version注解到字段上面
- 添加乐观锁插件即可
- 测试就自动带上了版本号
详细见:https://mp.baomidou.com/guide/optimistic-locker-plugin.html#%E4%B8%BB%E8%A6%81%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF
查询策略
注:分页查询需要添加以下插件:
1 //Spring boot方式
2 @EnableTransactionManagement
3 @Configuration
4 @MapperScan("com.baomidou.cloud.service.*.mapper*")
5 public class MybatisPlusConfig {
6
7 @Bean
8 public PaginationInterceptor paginationInterceptor() {
9 PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
10 // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
11 // paginationInterceptor.setOverflow(false);
12 // 设置最大单页限制数量,默认 500 条,-1 不受限制
13 // paginationInterceptor.setLimit(500);
14 // 开启 count 的 join 优化,只针对部分 left join
15 paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
16 return paginationInterceptor;
17 }
18 }
1 // 查询单个
2 @Test
3 void testSelectById(){
4 User user = userMapper.selectById(1L);
5 System.out.println(user);
6 }
7
8 // 查询多个
9 @Test
10 void testSelectBatchIds(){
11 List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));
12 users.forEach(System.out::println);
13 }
14
15 // 查询数量
16 @Test
17 void testSelectCount(){
18 Integer count = userMapper.selectCount(null);
19 System.out.println(count);
20 }
21
22 // 简单条件查询
23 @Test
24 void testSelectByMap(){
25 Map<String, Object> map = new HashMap<>();
26 map.put("name","zhangsan");
27 map.put("age",18);
28 List<User> users = userMapper.selectByMap(map);
29 users.forEach(System.out::println);
30 }
31
32 // 分页查询
33 @Test
34 void testSelectPage(){
35 Page<User> page = new Page<>();
36 Page<User> userPage = userMapper.selectPage(page, null);
37 List<User> users = userPage.getRecords();
38 users.forEach(System.out::println);
39 System.out.println(userPage.getSize());
40 System.out.println(userPage.getTotal());
41 System.out.println(userPage.getPages());
42 }
删除策略
1 // 删除一个
2 @Test
3 void testDeleteById(){
4 userMapper.deleteById(1L);
5 }
6
7 // 删除多个
8 @Test
9 void testDeleteBatchIds(){
10 userMapper.deleteBatchIds(Arrays.asList(2L,6L));
11 }
12
13 // 根据条件删除
14 @Test
15 void testDeleteByMap(){
16 HashMap<String, Object> map = new HashMap<>();
17 map.put("name","Tom");
18 userMapper.deleteByMap(map);
19 }
拓展
- 逻辑删除:并不是真的从数据库中删掉了,只是增加了一个判断而已
- 业务场景:管理员在后台可以看到被删除的记录,使用逻辑删除可以保证项目的安全和健壮性
- 物理删除:直接从数据库中删除
逻辑删除使用测试
- 添加逻辑删除字段
- 在实体类添加注解
- 在配置文件进行配置
- 注册Bean

1 @TableLogic // 逻辑删除字段注解 2 private Integer deleted;
1 # application.yml 加入配置(如果你的默认值和mp默认的一样,该配置可无) 2 mybatis-plus: 3 global-config: 4 db-config: 5 logic-delete-field: flag #全局逻辑删除字段值 3.3.0开始支持,详情看下面。 6 logic-delete-value: 1 # 逻辑已删除值(默认为 1) 7 logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
1 // 注册 Bean(3.1.1开始不再需要这一步)
2
3 import com.baomidou.mybatisplus.core.injector.ISqlInjector;
4 import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
5 import org.springframework.context.annotation.Bean;
6 import org.springframework.context.annotation.Configuration;
7
8 @Configuration
9 public class MyBatisPlusConfiguration {
10
11 @Bean
12 public ISqlInjector sqlInjector() {
13 return new LogicSqlInjector();
14 }
15 }
1 // 逻辑删除,删除一个
2 @Test
3 void testLogicDeleteById(){
4 userMapper.deleteById(1L);
5 }
性能分析
在开发的时候排除慢sql!
3.2.0版本以上参考:https://mp.baomidou.com/guide/p6spy.html
- 导入p6spy的maven依赖
- 在dev环境下配置文件进行配置
- spy.properties配置
3.2.0版本以下参考:https://mp.baomidou.com/guide/performance-analysis-plugin.html
条件构造器
我们平时写的sql,一般使用的最多的是一些条件,这些东西MP也帮助我们提供了
更多条件查询见官网:https://mp.baomidou.com/guide/wrapper.html#abstractwrapper
1 package com.coding;
2
3 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
4 import com.coding.mapper.UserMapper;
5 import com.coding.pojo.User;
6 import org.junit.jupiter.api.Test;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.boot.test.context.SpringBootTest;
9
10 @SpringBootTest
11 public class WrapperTest {
12 @Autowired
13 private UserMapper userMapper;
14 // 仅举一例,更多条件查询见官网
15 @Test
16 void testConditionSelect(){
17 QueryWrapper<User> wrapper = new QueryWrapper<>();
18 wrapper.eq("name","zhangsan") // 姓名 = zhangsan
19 .gt("age",18); // 年龄 > 18
20 userMapper.selectList(wrapper);
21 }
22 }
来源:https://www.cnblogs.com/ShallowPen/p/12651039.html