MybatisPlus没有对Mybatis做功能上的优化,只是简化了开发。
1、创建mybatis_plus项目步骤
①创建数据库,创建数据库表,添加数据,用于mp操作。
②创建springboot工程,2.2.1版本。
③pom.xml引入相关依赖。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <!-- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.0.5</version> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.20</version> </dependency> <!-- lombok 用来简化实体类 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
④安装lombok插件。
⑤配置application.properties文件(数据库)。
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=
⑥编写代码。
2、使用mp插入数据
mp 会自动生成 id(主键)值,数值为19位。mp 的 insert 方法返回的是影响的行数。
// 添加操作 @Test public void addUser() { User user = new User(); user.setName("jianjian"); user.setAge(23); user.setEmail("jianjian@qq.com"); // insert 为影响的行数; mp 自动生成 id(主键),19位 int insert = userMapper.insert(user); System.out.println("insert: " + insert); }
3、主键策略
①数据库自增长序列或字段。优点是排序方便。缺点是需要获取上一张表的最后一个数据的 id 值,麻烦。
②UUID:每次生成随机唯一的值。优点是不需要获取上一张表的最后一个数据的 id 值。缺点是排序不方便。
③redis 生成 id。redis 是单线程的,可以使用 redis 集群来获取更高的吞吐量。假设一个集群中有5 台 redis,可以初始化每台redis的值分别为1,2,3,4,5,然后步长都是 5,结果如下图。
④mybatis_plus 自带策略:snowflake 算法。
4、主键类型代码解释:TableId(type = IdType.AUTO)
①AUTO:自动增长。
②INPUT:自己设置id值。
③NONE:没有生成策略,自己输入id值。
④UUID:生成随机唯一id值。
⑤ID_WORKER:mp 自带策略,生成 19 位值,数字类型使用这种策略。
⑥ID_WORKER_STR:mp 自带策略,生成 19 位值,字符串类型使用这种策略。
5、mp实现自动填充
①在自动填充属性上面加上注解:TableField(fill = ..)。
@TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;
②创建类(handler 包,不要忘记在类上面加上 Component 注解),实现接口 MetaObjectHandler,实现接口里面的方法。
@Component public class MyMetaObjectHandler implements MetaObjectHandler { // 使用 mp 实现添加操作,该方法会执行 @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime", new Date(), metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); this.setFieldValByName("version", 1, metaObject); } // 使用 mp 实现修改操作,该方法会执行 @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime", new Date(), metaObject); } }
6、mp实现乐观锁
①表中添加字段 version,对应实体类添加版本号属性。
②在实体类版本号属性添加注解(@Version)。
@Version @TableField(fill = FieldFill.INSERT) private Integer version;
③配置乐观锁插件,建议专门写一个配置类。
// 乐观锁插件 @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); }
③测试。在修改之前,MybatisPlus会判断根据 id 得到的版本号和数据库中的版本号是否一致,如果一致就会修改成功,否则修改失败。
// 测试乐观锁 @Test public void testOptimisticLocker() { // 根据 id 查询数据 User user = userMapper.selectById(1522543846976765953L); // 进行修改 user.setAge(200); userMapper.updateById(user); }
7、mp实现分页
①配置分页插件。
// 分页插件 @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); }
②编写代码。
// 分页查询 @Test public void testPage() { // 创建 page 对象 // 传入两个参数:当前页 和 每页显示记录数 Page<User> page = new Page<>(1, 3); // 调用 mp 分页查询的方法 // 调用 mp 分页查询过程中,底层封装 // 把分页所有数据封装到 page 对象里面 userMapper.selectPage(page, null); // 通过 page 对象获取分页数据 System.out.println(page.getCurrent()); // 当前页 System.out.println(page.getRecords()); // 每页数据 list 集合 System.out.println(page.getSize()); // 每页显示记录数 System.out.println(page.getTotal()); // 总记录数 System.out.println(page.getPages()); // 总页数 System.out.println(page.hasNext()); // 是否有下一页 System.out.println(page.hasPrevious()); // 是否有上一页 }
8、删除
①物理删除:真实删除,将对应数据从数据库中删除,数据库表中再也没有此条数据。
②逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录。
逻辑删除步骤:
第一步:表中添加逻辑删除字段,对应实体类添加属性,属性添加注解(TableLogic)。
@TableLogic // 逻辑删除 private Integer deleted;
第二步:配置逻辑删除的插件。
// 逻辑删除插件 @Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); }
第三步:测试。如果配置成功,那么执行下面的删除方法时,只会把数据库中的相应数据的 deleted 字段改为 1。
// 测试逻辑删除 @Test public void testDeleteLogic() { int result = userMapper.deleteById(2L); System.out.println(result); }
补充:deleted 字段默认没有删除时为 0,删除时为 1。也可以通过将下面的代码写到配置文件当中,自己设定删除和未删除的值。
mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0
9、性能分析
性能分析拦截器,用于输出每条SQL语句及其执行时间。SQL性能执行分析,开发环境使用,超过指定时间,停止运行。有助于发现问题。
①配置插件。
/** * SQL 执行性能分析插件 * 开发环境使用,线上不推荐。 * maxTime:SQL 最大执行时间 * * 三种环境 * dev:开发环境 * test:测试环境 * prod:生产环境 */ @Bean @Profile({"dev", "test"}) public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor(); // ms,超过此处设置的时间则 SQL 不执行 performanceInterceptor.setMaxTime(500); performanceInterceptor.setFormat(true); return performanceInterceptor; }
②在配置文件中设置开发环境。
spring.profiles.active=dev
③测试:例如执行添加操作,在idea中可以看到SQL语句以及执行时间。
10、 mp实现复杂条件查询
使用QueryWrapper构建条件。
// mp 实现复杂查询操作 @Test public void testSelectQuery() { QueryWrapper<User> wrapper = new QueryWrapper<>(); // ge(>=)、gt(>)、le(<=)、lt(<)、eq(=)、ne(!=) // wrapper.ge("age", 23); // between // wrapper.between("age", 20, 30); // like // wrapper.like("name", "dai"); // last:拼接到SQL语句的最后 // wrapper.last("limit 1"); // 查询指定的列 wrapper.select("id", "name"); List<User> users = userMapper.selectList(wrapper); System.out.println(users); }