Mybatisplus

  • 1. mybatis的插件机制
  • 2. 拦截器示例
    • 2.1 新建拦截器文件【MyInterceptor 】
    • 2.2 把拦截器文件注入到spring容器中
    • 2.3 执行测试用例update方法
    • 2.4 执行结果
  • 3. 执行分析插件
    • 3.1 配置
    • 3.2 编写测试用例
    • 3.3 执行结果
  • 4. 性能分析插件
    • 4.1 在【mybatis-config.xml】里添加插件配置
    • 4.2 执行测试用例【testSelect】
    • 4.3 执行结果

1. mybatis的插件机制

MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法
调用包括:

  1. Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  2. ParameterHandler (getParameterObject, setParameters)
  3. ResultSetHandler (handleResultSets, handleOutputParameters)
  4. StatementHandler (prepare, parameterize, batch, update, query)

我们看到了可以拦截Executor接口的部分方法,比如update,query,commit,rollback等方法,还有其他接口的一些方法等。

总体概括为:

  1. 拦截执行器的方法
  2. 拦截参数的处理
  3. 拦截结果集的处理
  4. 拦截Sql语法构建的处理

2. 拦截器示例

2.1 新建拦截器文件【MyInterceptor 】

【method = “update”】可以通过method指定拦截方法,该实例拦截的是【update】方法。

@Intercepts({@Signature(type = Executor.class,method = "update",args = {MappedStatement.class, Object.class})})
public class MyInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {//拦截方法,具体业务逻辑编写的位置System.out.println("拦截了update方法");return invocation.proceed();}@Overridepublic Object plugin(Object target) {//创建target对象的代理对象,目的是将当前拦截器加入到该对象中return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {//属性设置}
}

2.2 把拦截器文件注入到spring容器中

/*** @author LongXi* @create 2021-09-24 20:56*/
@MapperScan("cn.itcast.mp.mapper")
@Configuration
public class MyBatisPlusConfig {@Beanpublic PaginationInterceptor paginationInterceptor(){return new PaginationInterceptor();}/*** 自定义拦截器*/@Beanpublic MyInterceptor myInterceptor(){return new MyInterceptor();}
}

2.3 执行测试用例update方法

    @Testpublic void testUpdate() {User user = new User();user.setAge(20); //更新的字段user.setPassword("8888888");QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("user_name", "zhaoliu"); //匹配user_name = zhaoliu 的用户数据//根据条件做更新int result = this.userMapper.update(user, wrapper);System.out.println("result => " + result);}

2.4 执行结果

[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@55b8dbda] was not registered for synchronization because synchronization is not active
拦截了update方法
[main] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Fetching JDBC Connection from DataSource
[main] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [HikariProxyConnection@101601906 wrapping com.mysql.cj.jdbc.ConnectionImpl@7c18432b] will not be managed by Spring
[main] [cn.itcast.mp.mapper.UserMapper.update]-[DEBUG] ==>  Preparing: UPDATE tb_user SET password=?, age=? WHERE user_name = ?
[main] [cn.itcast.mp.mapper.UserMapper.update]-[DEBUG] ==> Parameters: 8888888(String), 20(Integer), zhaoliu(String)
[main] [cn.itcast.mp.mapper.UserMapper.update]-[DEBUG] <==    Updates: 2
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@55b8dbda]
result => 2

我们的拦截语句【拦截了update方法】被输出,说明拦截器起作用了。

3. 执行分析插件

在MP中提供了对SQL执行的分析的插件,可用作阻断全表更新、删除的操作,
注意:该插件仅适用于开发环境,不适用于生产环境。

3.1 配置

SpringBoot配置:

@Bean
public SqlExplainInterceptor sqlExplainInterceptor(){SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();List<ISqlParser> sqlParserList = new ArrayList<>();// 攻击 SQL 阻断解析器、加入解析链sqlParserList.add(new BlockAttackSqlParser());sqlExplainInterceptor.setSqlParserList(sqlParserList);
return sqlExplainInterceptor;
}

3.2 编写测试用例

    // 测试全局阻断器@Testpublic void testUpdateAll() {//根据条件做更新User user = new User();user.setAge(20); //更新的字段user.setPassword("8888888");//根据条件做更新int result = this.userMapper.update(user, new QueryWrapper<>());System.out.println("result => " + result);}

3.3 执行结果

跟预期一样,被阻断了,这种操作不被允许

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error updating database.  Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of table update operation
### Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of table update operationat org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77)at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)at com.sun.proxy.$Proxy56.update(Unknown Source)at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:294)at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:63)at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:62)at com.sun.proxy.$Proxy60.update(Unknown Source)at cn.itcast.mp.TestUserMapper.testUpdateAll(TestUserMapper.java:95)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)

把SQL拿出来看一下

[main] [com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser]-[DEBUG] Original SQL: UPDATE tb_user  SET password=?,age=?
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5b22b970]

没有条件,是全表更新。

4. 性能分析插件

性能分析拦截器,用于输出每条 SQL 语句及其执行时间,可以设置最大执行时间,超过时间会抛出异常。
注意:

该插件只用于开发环境,不建议生产环境使用。

4.1 在【mybatis-config.xml】里添加插件配置

    <plugins><plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></plugin><!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 --><plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor"><property name="maxTime" value="100" /><!--SQL是否格式化 默认false--><property name="format" value="true" /></plugin></plugins>

maxTime 指的是 sql 最大执行时长,以毫秒为单位。

4.2 执行测试用例【testSelect】

    @Testpublic void testSelect(){QueryWrapper<User> wrapper = new QueryWrapper<>();//SELECT id,name,age FROM tb_user WHERE name = ? OR age = ?wrapper.eq("name", "王五").or().eq("age", 21).select("id","name","age"); //指定查询的字段List<User> users = this.userMapper.selectList(wrapper);for (User user : users) {System.out.println(user);}}

4.3 执行结果

[main] [cn.itcast.mp.mapper.UserMapper.selectList]-[DEBUG] ==>  Preparing: SELECT id,name,age FROM tb_user WHERE name = ? OR age = ?
[main] [cn.itcast.mp.mapper.UserMapper.selectList]-[DEBUG] ==> Parameters: 王五(String), 21(Integer)
[main] [cn.itcast.mp.mapper.UserMapper.selectList]-[DEBUG] <==      Total: 2Time:24 ms - ID:cn.itcast.mp.mapper.UserMapper.selectList
Execute SQL:SELECTid,name,age FROMtb_user WHEREname = '王五' OR age = 21[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1ecfcbc9]
User(id=2, userName=null, password=null, name=李四, age=21, mail=null, address=null)
User(id=3, userName=null, password=null, name=王五, age=22, mail=null, address=null)

可以看到,sql被格式化了,执行时间也打出来了。

如果执行时间操作了测试时间,就会提示你优化了。

Mybatisplus插件相关推荐

  1. 第 7 章 MybatisPlus 插件

    第 7 章 MybatisPlus 插件 1.插件机制概述 MybatisPlusInterceptor 核心插件 MybatisPlus 通过插件(Interceptor)可以做到拦截四大对象(Ex ...

  2. 解决MybatisPlus插件分页查询不起作用,总是查询全部数据问题

    问题描述: 在使用mybatisplus插件进行分页查询时分页参数不起作用,总是查出来全部数据. 原因分析: 查看打印的sql日志发现sql后面并没有limit条件,怀疑是缺少配置. 解决方案: 查阅 ...

  3. idea mybatisplus 插件使用

    在plugin中安装mybatisplus 插件 使用 配置数据库 生成代码 表新增字段,重新生成实体类覆盖 因业务需求,表中可能会时不时增加一些字段,大多情况下实体类中不会添加表中没有的字段,因此可 ...

  4. Mybatis-Plus插件配置

    yml配置 1 # Mybatis-Plus 2 mybatis-plus: 3 # 配置mapper的扫描,找到所有的mapper.xml映射文件 4 mapper-locations: com.x ...

  5. MyBatisPlus插件扩展_OptimisticLockerInterceptor乐观锁插件的使用

    场景 项目搭建专栏: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/37194 简介 意图: 当要更新一条记录的时候,希望这条记录没有被别 ...

  6. MyBatisPlus插件扩展_PerformanceInterceptor性能分析插件的使用

    场景 项目搭建专栏: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/37194 简介 性能分析拦截器,用于输出每条 SQL 语句及其执行时 ...

  7. MyBatisPlus插件扩展_SqlExplainInterceptor执行分析插件的使用

    场景 项目搭建专栏: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/37194 简介 SQL 执行分析拦截器[ 目前只支持 MYSQL-5 ...

  8. MyBatisPlus插件扩展_PaginationInterceptor分页插件的使用

    场景 项目搭建专栏: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/37194 实现 配置插件 来到项目下的applicationCont ...

  9. MyBatis-Plus插件

    文章目录 一. 分页插件 1. 添加配置类 2. 测试 二. xml自定义分页 1. UserMapper中定义接口方法 2. UserMapper.xml中编写SQL 3. 测试 三. 乐观锁 1. ...

最新文章

  1. rn+与android+交互,React native 与Android原生交互方式(一)
  2. c语言位段sizeof,C语言位段的介绍
  3. Apache服务器的WSASocket failed to open the inherited socket错误
  4. 解决弹出框滚动穿透的问题(问题是body也会滚动)
  5. .net mvc web api 返回 json 内容时过滤值为null的属性
  6. vc获取n卡编号_电脑入门知识:通过显卡型号中字母和数字判断显卡性能
  7. 背景图层和普通图层的区别_新手如何在PS中创建图层?不容错过的7种方法,你值得学习...
  8. pytorch dropout_PyTorch初探MNIST数据集
  9. CNN中的卷积核及TensorFlow中卷积的各种实现
  10. spring-boot-devtools热加载不起作用
  11. HAOI(十二省联考)2019 qwq记
  12. SetTimer函数和 KillTimer函数
  13. qt中的句柄类,实体类
  14. 吉林省教育学院学报杂志社吉林省教育学院学报编辑部2022年第9期目录
  15. 安服工程师的岗位职责
  16. uni-app 地图拖拽后,回到我的位置
  17. 个人外汇买卖能不能一直等到赢利再平仓
  18. 日照喜来登酒店启幕;万豪旗下万枫酒店品牌首次亮相宁波;平湖万怡酒店正式开业 | 全球旅报...
  19. [有感而发]与刺客独行
  20. python 拉普拉斯锐化_Python+OpenCV拉普拉斯图像锐化

热门文章

  1. MATLAB学习(4)——min
  2. 并发编程实战——锁分段
  3. 2015-04-11一些知识点
  4. maven简单工具命令
  5. Python 第三方扩展库
  6. (133)FPGA面试题-Xilinx FPGA Block RAM的三种写模式是什么?
  7. (89)FPGA三分频设计,面试必问(十三)(第18天)
  8. (34)FPGA面试技能提升篇(高速SERDES)
  9. Verilog inout语句使用方法及技巧
  10. Verilog实现3分频实例