前言
目前正在出一个Mybatis Plus
系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
之前给大家讲过Mybatis
教程,而MyBatis-Plus
是一个 MyBatis
的增强工具,在MyBatis
的基础上只做增强不做改变,为简化开发、提高效率而生。大家需要注意的是它只是一个工具,大家需要掌握和重点学习的依然是Mybatis
,在熟练掌握基础的情况下使用MyBatis-Plus
会达到事半功倍的效果。
好了, 废话不多说直接开整吧~
自定义插件开发
之前带大家使用了它的一些内置插件,Mybatis Plus
插件开发很简单,我们可以先看下之前使用的OptimisticLockerInnerInterceptor
插件源码
java
public class OptimisticLockerInnerInterceptor implements InnerInterceptor {
......
}
主要是通过实现InnerInterceptor
接口,它的实现机制主要是通过拦截器
实现的,MyBatis Plus
拦截器对MyBatis
的拦截器进行了一层包装,使我们处理起来更加的方便,下面一起看下它的接口
java
public interface InnerInterceptor {
default boolean willDoQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
return true;
}
default void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
}
default boolean willDoUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException {
return true;
}
default void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException {
}
default void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
}
default void beforeGetBoundSql(StatementHandler sh) {
}
default void setProperties(Properties properties) {
}
}
可以看到对各种操作都有相应的拦截方法,下面我们就来实现一个自己的插件,以查询为例:
java
package com.springboot.all.mybatisplus.plugin;
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectBody;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import java.sql.Connection;
@Slf4j
public class MybatisPlusTestPlugin extends JsqlParserSupport implements InnerInterceptor {
@Override
public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);
MappedStatement ms = mpSh.mappedStatement();
if (InterceptorIgnoreHelper.willIgnoreTenantLine(ms.getId())) {
return;
}
PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql();
mpBs.sql(parserMulti(mpBs.sql(), null));
}
@Override
protected void processSelect(Select select, int index, String sql, Object obj) {
SelectBody selectBody = select.getSelectBody();
PlainSelect plainSelect = (PlainSelect) selectBody;
plainSelect.setWhere(plainSelect.getWhere());
log.info("sql ---> {}", plainSelect);
}
}
注册插件:
java
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 注册乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
// 注入分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 注入自定义插件
interceptor.addInnerInterceptor(new MybatisPlusTestPlugin());
return interceptor;
}
下面测试下看看是否生效了~ 使用以下查询
java
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.like("name", "x");
List<User> userList = userMapper.selectList(queryWrapper);
yaml
2024-02-22 10:30:37.067 INFO 30108 --- [nio-8080-exec-1] c.s.a.m.plugin.MybatisPlusTestPlugin : sql ---> SELECT id, name, age, version, create_at, update_at FROM sys_user WHERE (name LIKE ?)
==> Preparing: SELECT id, name, age, version, create_at, update_at FROM sys_user WHERE (name LIKE ?)
==> Parameters: %x%(String)
<== Columns: id, name, age, version, create_at, update_at
<== Row: 1731552348403740673, xiaohong2, 22, 1, 2023-12-11 10:55:31, 2023-12-11 11:17:04
<== Row: 1731552348403740674, xiaohong3, 23, 1, 2023-12-11 10:55:31, 2023-12-11 11:17:04
<== Row: 1731552348470849537, xiaohong4, 24, 1, 2023-12-11 10:55:31, 2023-12-11 11:17:04
<== Row: 1731552348470849538, xiaohong5, 25, 1, 2023-12-11 10:55:31, 2023-12-11 11:17:04
<== Total: 4
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3f7e80eb]
可以看到有日志打印,说明拦截方法已经生效了。那如何在拦截器中修改sql
呢?在平时业务开发中都会有这种拦截的场景,比如不同的权限返回的字段不同,查询条件也不同,通过统一拦截可以提高系统的安全性和可维护性 这里我们可以借助JsqlParserSupport
提供的API
来封装sql
java
@Override
protected void processSelect(Select select, int index, String sql, Object obj) {
// 解析SQL
SelectBody selectBody = select.getSelectBody();
PlainSelect plainSelect = (PlainSelect) selectBody;
// 构建eq对象
EqualsTo equalsTo = new EqualsTo(new Column("age"), new StringValue("22"));
// 将原来的条件和新构建的条件合在一起
AndExpression andExpression = new AndExpression(plainSelect.getWhere(), equalsTo);
// 重新封装where条件
plainSelect.setWhere(andExpression);
log.info("sql ---> {}", plainSelect);
}
可以看到sql
已经被拦截并修改了
vbnet
2024-02-22 10:46:29.043 INFO 29524 --- [nio-8080-exec-1] c.s.a.m.plugin.MybatisPlusTestPlugin : sql ---> SELECT id, name, age, version, create_at, update_at FROM sys_user WHERE (name LIKE ?) AND age = '22'
==> Preparing: SELECT id, name, age, version, create_at, update_at FROM sys_user WHERE (name LIKE ?) AND age = '22'
==> Parameters: %x%(String)
<== Columns: id, name, age, version, create_at, update_at
<== Row: 1731552348403740673, xiaohong2, 22, 1, 2023-12-11 10:55:31, 2023-12-11 11:17:04
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@37ae5cdd]
其它增删改也是类似的处理,就不一一演示了
java
@Override
protected void processInsert(Insert insert, int index, String sql, Object obj) {
insert.getColumns().add(new Column("name"));
((ExpressionList) insert.getItemsList()).getExpressions().add(new StringValue("xiaoming"));
}
@Override
protected void processUpdate(Update update, int index, String sql, Object obj) {
update.addUpdateSet(new Column("name"), new StringValue("xiaoming"));
}
@Override
protected void processDelete(Delete delete, int index, String sql, Object obj) {
//... 和上面;类似
}
感兴趣的小伙伴可以看看开源的插件源码学习下别人是怎么处理的~
结束语
Mybatis Plus
系列到这里就结束了~
本着把自己知道的都告诉大家,如果本文对有所帮助,点赞+关注
鼓励一下呗~
MybatisPlus教程相关文章
往期Nginx教程相关文章
往期Docker教程相关文章
往前Shell脚本编程相关文章
- 一起来学Shell脚本编程(一)
- 一起来学Shell脚本编程(二)
- 一起来学Shell脚本编程(三)
- 一起来学Shell脚本编程(四)
- 一起来学Shell脚本编程(五)
- 一起来学Shell脚本编程(六)
- 一起来学Shell脚本编程(七)
往期Linux相关文章
- 一起来学Linux命令(一)
- 一起来学Linux命令(二)
- 一起来学Linux命令(三)
- 一起来学Linux命令(四)
- 一起来学Linux命令(五)
- 一起来学Linux命令(六)
- 一起来学Linux命令(七)
- 一起来学Linux命令(八)
- 一起来学Linux命令(九)
- 一起来学Linux命令(十)
往期面试题相关文章
- 查漏补缺第一期(Redis相关)
- 查漏补缺第二期(synchronized & 锁升级)
- 查漏补缺第三期(分布式事务相关)
- 查漏补缺第四期(Mysql相关)
- 查漏补缺第五期(HashMap & ConcurrentHashMap)
- 查漏补缺第六期(京东一面)
- 查漏补缺第七期(美团到店一面)
- 查漏补缺第八期(阿里一面)
- 查漏补缺第九期(阿里二面)
- 查漏补缺第十期(网易实习一面)
- 查漏补缺第十一期(网易实习二面)
- 查漏补缺第十二期(网易实习三面)
- 查漏补缺第十三期(滴滴实习一面)
- 查漏补缺第十四期(滴滴实习二面)
- 查漏补缺第十五期(华为一面)
- 查漏补缺第十六期(华为二面)
- 查漏补缺第十七期(华为三面)
- 查漏补缺第十八期(你了解class文件吗)
项目源码(源码已更新 欢迎star⭐️)
往期设计模式相关文章
- 一起来学设计模式之认识设计模式
- 一起来学设计模式之单例模式
- 一起来学设计模式之工厂模式
- 一起来学设计模式之建造者模式
- 一起来学设计模式之原型模式
- 一起来学设计模式之适配器模式
- 一起来学设计模式之桥接模式
- 一起来学设计模式之组合模式
- 一起来学设计模式之装饰器模式
- 一起来学设计模式之外观模式
- 一起来学设计模式之享元模式
- 一起来学设计模式之代理模式
- 一起来学设计模式之责任链模式
- 一起来学设计模式之命令模式
- 一起来学设计模式之解释器模式
- 一起来学设计模式之迭代器模式
- 一起来学设计模式之中介者模式
- 一起来学设计模式之备忘录模式
- 一起来学设计模式之观察者模式
- 一起来学设计模式之状态模式
- 一起来学设计模式之策略模式
- 一起来学设计模式之模板方法模式
- 一起来学设计模式之访问者模式
- 一起来学设计模式之依赖注入模式
设计模式项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
项目源码(源码已更新 欢迎star⭐️)
往期并发编程内容推荐
- Java多线程专题之线程与进程概述
- Java多线程专题之线程类和接口入门
- Java多线程专题之进阶学习Thread(含源码分析)
- Java多线程专题之Callable、Future与FutureTask(含源码分析)
- 面试官: 有了解过线程组和线程优先级吗
- 面试官: 说一下线程的生命周期过程
- 面试官: 说一下线程间的通信
- 面试官: 说一下Java的共享内存模型
- 面试官: 有了解过指令重排吗,什么是happens-before
- 面试官: 有了解过volatile关键字吗 说说看
- 面试官: 有了解过Synchronized吗 说说看
- Java多线程专题之Lock锁的使用
- 面试官: 有了解过ReentrantLock的底层实现吗?说说看
- 面试官: 有了解过CAS和原子操作吗?说说看
- Java多线程专题之线程池的基本使用
- 面试官: 有了解过线程池的工作原理吗?说说看
- 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
- 面试官: 阻塞队列有了解过吗?说说看
- 面试官: 阻塞队列的底层实现有了解过吗? 说说看
- 面试官: 同步容器和并发容器有用过吗? 说说看
- 面试官: CopyOnWrite容器有了解过吗? 说说看
- 面试官: Semaphore在项目中有使用过吗?说说看(源码剖析)
- 面试官: Exchanger在项目中有使用过吗?说说看(源码剖析)
- 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
- 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
- 面试官: Phaser有了解过吗?说说看
- 面试官: Fork/Join 有了解过吗?说说看(含源码分析)
- 面试官: Stream并行流有了解过吗?说说看