如果对 MyBatis-Plus 不了解,请先看 SpringBoot 整合 MyBatis-Plus
一、拦截器
MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截方法的调用,分别为:Executor(执行器的方法)、ParameterHandler(参数的处理)、ResultSetHandler(结果集的处理)、StatementHandler(SQL 语法构建的处理)。
1、定义自定义拦截器
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import java.util.Properties;
@Intercepts({@Signature(
type = Executor.class,
// 设置指定类型的SQL
method = "update",
args = {MappedStatement.class,Object.class})})
public class MyInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 拦截方法,具体业务逻辑编写的位置
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
// 创建target对象的代理对象,目的是将当前拦截器加入到该对象中
return Plugin.wrap(target,this);
}
@Override
public void setProperties(Properties properties) {
// 属性设置
}
}
2、注入自定义的拦截器
@Bean
public MyInterceptor myInterceptor(){
return new MyInterceptor();
}
二、性能分析插件
性能分析拦截器,用于输出每条 SQL 语句及其执行时间。该插件 3.2.0
以上版本移除推荐使用第三方扩展 执行 SQL 分析打印 功能。
三、乐观锁插件
使用场景:当要更新一条记录的时候,希望这条记录没有被别人更新。乐观锁的实现方法:取出记录时,获取当前 version,更新时带上 version,如果 version 不对,则更新失败。
配置文件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
为表添加 version 字段并设置初始值为 1,并为实体类添加 version 字段,并且添加@Version 注解。仅支持 updateById(id)和 update(entity,wrapper)方法。
例子:
User user = new User();
user.setId(2);
user.setPassword("101010101");
// 当version的值和数据库的version的值相同时才执行
user.setVersion(1);
// UPDATE tb_user SET user_password=?, user_grade=?, user_version=? WHERE user_id=? AND user_version=?
System.out.println(user.updateById());
四、SQL 注入器
在 MP 中如果 BaseMapper 中的方法不够用户,该如何添加呢?
1、编写 MyBaseMapper,定义自定义方法。
public interface MyBaseMapper<T> extends BaseMapper<T> {
List<T> findAll();
}
2、将 Mapper 继承自己编写 MyBaseMapper
public interface UserMapper extends MyBaseMapper<User> {
}
3、为自己定义的方法创建类继承 AbstractMethod 。
public class FindAll extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
String sqlMethod="findAll";
String sql="select * from "+tableInfo.getTableName();
SqlSource sqlSource=languageDriver.createSqlSource(configuration,sql,modelClass);
// 根据SQL语句的类型调用不同的方法。
return this.addSelectMappedStatementForTable(mapperClass,sqlMethod,sqlSource,tableInfo);
}
}
4、创建自己的 MySqlInjector,将原来的方法和自定义的方法注入进去。
public class MySqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> list = new ArrayList<>();
// 获取父类中的集合
list.addAll(super.getMethodList(mapperClass));
// 扩充自定义的方法
list.add(new FindAll());
return list;
}
}
5、将自己创建的 MySqlInjector 交给 Spring 管理
@Bean
public MySqlInjector mySqlInjector(){
return new MySqlInjector();
}
6、测试
userMapper.findAll()
五、自动填充功能
在插入或者更新数据时,我们希望有些字段可以自动填充数据。在 MP 中提供了这样的功能,可以实现自动填充。
在字段上添加@TableField 注解,例如:
1、修改实体类
@TableField(value = "user_grade",fill = FieldFill.INSERT)
private int grade;
2、填充的类型:
值 | 作用 |
---|---|
DEFAULT | 默认不处理 |
INSERT | 插入时填充字段 |
UPDATE | 更新时填充字段 |
INSERT_UPDATE | 插入和更新时填充字段 |
3、配置填充规则:
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 先获取 grade 的值,再进行判断,如果为空,就进行填充。
Object grade=getFieldValByName("grade",metaObject);
if(((Integer)grade) ==0){
setFieldValByName("grade",999,metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
}
}
4、测试:
User user=new User();
user.setName("Yi-Xing");
userMapper.insert(user);
六、逻辑删除
所谓逻辑删除就是将数据标记为删除,而并非真正的物理删除(非 DELETE 操作),查询时需要携带状态条件,确保被标记的数据不被查询到。这样做的目的就是避免数据被真正的删除。
1、修改表和实体类
修改表结构,添加 deleted 字段,用于表示数据是否被删除,1 代表删除,0 代表未删除。同时也修改实体类,添加 deleted 属性并添加@TableLogic 注解
@TableLogic
@TableField("user_deleted")
private int deleted;
2、配置
mybatis-plus:
db-config:
# 删除状态为1
logic-delete-value: 1
# 未删除状态为0
logic-not-delete-value: 0
3、测试
userMapper.deleteById(2)
标题:MyBatis-Plus 的更多功能
作者:Yi-Xing
地址:http://47.94.239.232/articles/2020/01/14/1578992228126.html
博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!