本篇基于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