2021年7月21日 14点05分
看尚硅谷新讲的尚医通,这个MP的文档多了新东西:
依赖版本:
springBoot版本 2.2.1.RELEASE
<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.3.1</version> </dependency> <!--mysql依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--lombok用来简化实体类--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>
但是拉下来Spring报错,死活找不到版本
我这里干脆换版本了:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.atguigu</groupId> <artifactId>mybatis_plus</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mybatis_plus</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <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.4.1</version> </dependency> <!--mysql依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--lombok用来简化实体类--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
一、自动填充
package com.atguigu.mybatis_plus.entity; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import java.util.Date; @Data public class User { @TableId(type = IdType.ASSIGN_ID) // 默认雪花算法的主键策略 @TableId(type = IdType.AUTO) 自增策略 private Long id; private String name; private Integer age; private String email; // 自动填充注解? 需要实现 元对象处理器接口,自定义实现方法 @TableField(value = "createTime", fill = FieldFill.INSERT) private Date createTime; //create_time @TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE) private Date updateTime; }
元对象处理器接口实现:
package com.atguigu.mybatis_plus.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.util.Date; /** * 自动填充 * 需求描述: * 项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。 * 我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作 * 1.1数据库修改 * 在User表中添加datetime类型的新的字段 create_time、update_time * * */ @Component public class CustomMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); this.setFieldValByName("recordVersion", 1, metaObject); } @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime",new Date(),metaObject); } }
二、乐观锁
项目里面的持久层框架时ActiveJdbc,有这样的应用场景,但是框架这块没提供相关的封装
实现是人肉代码完成,程序逻辑有一点点封装
MP这里就配置一下就行了
package com.atguigu.mybatis_plus.entity; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import java.util.Date; @Data public class User { @TableId(type = IdType.ASSIGN_ID) // 默认雪花算法的主键策略 @TableId(type = IdType.AUTO) 自增策略 private Long id; private String name; private Integer age; private String email; // 自动填充注解? 需要实现 元对象处理器接口,自定义实现方法 @TableField(value = "createTime", fill = FieldFill.INSERT) private Date createTime; //create_time @TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE) private Date updateTime; /** * 乐观锁 * 场景 * 主要适用场景:当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新 * 乐观锁实现方式: * 取出记录时,获取当前version * 更新时,带上这个version * 执行更新时, set version = newVersion where version = oldVersion * 如果version不对,就更新失败 * 接下来介绍如何在Mybatis-Plus项目中,使用乐观锁: */ @Version @TableField(value = "recordVersion", fill = FieldFill.INSERT) // 设置默认值 private Integer recordVersion; @TableLogic private Integer deleted; // ALTER TABLE `user` ADD COLUMN `deleted` boolean DEFAULT false }
编写配置类:
package com.atguigu.mybatis_plus.config; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @MapperScan("com.atguigu.mybatis_plus.mapper") public class MybatisPlusConfiguration { /** * 乐观锁插件 已过时对象写法 */ // @Bean // public OptimisticLockerInterceptor optimisticLockerInterceptor() { // return new OptimisticLockerInterceptor(); // } /** * 分页插件 * 已过时? */ // @Bean // public PaginationInterceptor paginationInterceptor() { // return new PaginationInterceptor(); // } @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ // mp插件接口 MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 添加乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); // 添加分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }
乐观锁测试:
// 乐观锁案例 @Test void testingForOptimisticLocker() { // 首先插入一条记录,检查是否自动插入RecordVersion User user = new User(); user.setAge(24); user.setName("小红"); user.setEmail("21312qasdq@qq.com"); int insert = userMapper.insert(user); // 然后使用ID查询, 更改这条记录, 检查版本会不会更改为2 User user1 = userMapper.selectById(user.getId()); // 不确定这样能否有效获取ID, 建议从库里拿数据写死 user1.setName("新小红"); userMapper.updateById(user1); }
三、支持逻辑删除
package com.atguigu.mybatis_plus.entity; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import java.util.Date; @Data public class User { @TableId(type = IdType.ASSIGN_ID) // 默认雪花算法的主键策略 @TableId(type = IdType.AUTO) 自增策略 private Long id; private String name; private Integer age; private String email; // 自动填充注解? 需要实现 元对象处理器接口,自定义实现方法 @TableField(value = "createTime", fill = FieldFill.INSERT) private Date createTime; //create_time @TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE) private Date updateTime; /** * 乐观锁 * 场景 * 主要适用场景:当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新 * 乐观锁实现方式: * 取出记录时,获取当前version * 更新时,带上这个version * 执行更新时, set version = newVersion where version = oldVersion * 如果version不对,就更新失败 * 接下来介绍如何在Mybatis-Plus项目中,使用乐观锁: */ @Version @TableField(value = "recordVersion", fill = FieldFill.INSERT) // 设置默认值 private Integer recordVersion; @TableLogic private Integer deleted; // ALTER TABLE `user` ADD COLUMN `deleted` boolean DEFAULT false }
配置文件相关定义:
spring: datasource: url: jdbc:mysql://localhost:3308/atguigu-syt?serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 #mybatis日志 mybatis-plus: global-config: db-config: id-type: auto #全局设置主键生成策略 # 设置逻辑删除值标准 (默认值) logic-delete-value: 1 logic-not-delete-value: 0 configuration: # 日志输出标准 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
测试类的单元方法:
/** * 2、逻辑删除 * 2.1物理删除和逻辑删除 * 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据 * 逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录 * * 逻辑删除的使用场景: * 可以进行数据恢复 * 有关联数据,不便删除 * * 2.2 逻辑删除实现流程 * 2.2.1数据库修改 * 添加 deleted字段 * ALTERTABLE `user` ADD COLUMN `deleted` boolean DEFAULT false * * 2.2.2实体类修改 * 添加deleted 字段,并加上 @TableLogic 注解 * @TableLogic * private Integer deleted; * * 2.2.3配置(可选) * application.properties 加入以下配置,此为默认值,如果你的默认值和mp默认的一样,该配置可无 * mybatis-plus.global-config.db-config.logic-delete-value=1 * mybatis-plus.global-config.db-config.logic-not-delete-value=0 * * 2.2.4 测试 * 测试后发现,数据并没有被删除,deleted字段的值由0变成了1 * 测试后分析打印的sql语句,是一条update * 注意:被删除前,数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操作 * @Test * public void testLogicDelete() { * int result = userMapper.deleteById(1L); * system.out.println(result); * } * * 2.2.5测试逻辑删除后的查询 * MyBatis Plus中查询操作也会自动添加逻辑删除字段的判断 * @Test * public void testLogicDeleteSelect() { * List<User> users = userMapper.selectList(null); * users.forEach(System.out::println); * } * * */ @Test public void testingForLogicDelete() { userMapper.deleteById(1); /** * ==> Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0 * ==> Parameters: 1(Integer) * <== Updates: 1 */ List<User> users = userMapper.selectList(null); /** * ==> Preparing: SELECT id,name,age,email,createTime,updateTime,recordVersion,deleted FROM user WHERE deleted=0 * ==> Parameters: * <== Columns: id, name, age, email, createTime, updateTime, recordVersion, deleted * <== Row: 2, Jack, 20, test2@baomidou.com, null, null, null, 0 * <== Row: 3, Tom, 28, test3@baomidou.com, null, null, null, 0 * <== Row: 4, Sandy, 21, test4@baomidou.com, null, null, null, 0 * <== Row: 5, Billie, 24, test5@baomidou.com, null, null, null, 0 * <== Row: 1417674045524021250, lucy, 20, 1243@qq.com, null, null, null, 0 * <== Row: 1417680764933292034, 王五AAA, 20, 1243@qq.com, 2021-07-21 11:00:08, 2021-07-21 11:01:07, 2, 0 * <== Total: 6 */ users.forEach(System.out::println); }