插件扩展
1.1 Mybatis 插件机制简介
1.1.1 插件机制:
Mybatis 通过插件(Interceptor) 可以做到拦截四大对象相关方法的执行,根据需求,完成相关数据的动态改变。
Executor
StatementHandler
ParameterHandler
ResultSetHandler
1.1.2 插件原理
四大对象的每个对象在创建时,都会执行 interceptorChain.pluginAll(),会经过每个插件对象的 plugin()方法,目的是为当前的四大对象创建代理。代理对象就可以拦截到四大对象相关方法的执行,因为要执行四大对象的方法需要经过代理.
2.1 分页插件
com.baomidou.mybatisplus.plugins.PaginationInterceptor
添加插件
<plugins>
<!--
| 分页插件配置
| 插件提供二种方言选择:1、默认方言 2、自定义方言实现类,两者均未配置则抛出异常!
| overflowCurrent 溢出总页数,设置第一页 默认false
| optimizeType Count优化方式 ( 版本 2.0.9 改为使用 jsqlparser 不需要配置 )
| -->
<!-- 注意!! 如果要支持二级缓存分页使用类 CachePaginationInterceptor 默认、建议如下!! -->
<plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor">
<property name="sqlParser" ref="自定义解析类、可以没有" />
<property name="localPage" value="默认 false 改为 true 开启了 pageHeper 支持、可以没有" />
<property name="dialectClazz" value="自定义方言类、可以没有" />
</plugin>
</plugins>
或者
@EnableTransactionManagement
@Configuration
@MapperScan("com.baomidou.cloud.service.*.mapper*")
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
测试
public class TestMP01 {
private ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
private EmployeeMapper employeeMapper = ctx.getBean("employeeMapper", EmployeeMapper.class);
/**
* 测试分页插件
*/
@Test
public void testPage() {
Page<Employee> page = new Page<>(1, 1);
List<Employee> emps = employeeMapper.selectPage(page, null);
System.out.println(emps);
System.out.println("总条数:" + page.getTotal());
System.out.println("当前页码: " + page.getCurrent());
System.out.println("总页码:" + page.getPages());
System.out.println("每页显示的条数:" + page.getSize());
System.out.println("是否有上一页: " + page.hasPrevious());
System.out.println("是否有下一页: " + page.hasNext());
//将查询的结果封装到page对象中
page.setRecords(emps);
}
}
结果执行
Preparing: SELECT id AS id,last_name AS lastName,email,gender,age,version FROM tbl_employee LIMIT 0,1
3.1 执行分析插件
com.baomidou.mybatisplus.plugins.SqlExplainInterceptor
- SQL 执行分析拦截器,只支持 MySQL5.6.3 以上版本
- 该插件的作用是分析 DELETE UPDATE 语句,防止小白或者恶意进行 DELETE UPDATE 全表操作
- 只建议在开发环境中使用,不建议在生产环境使用
- 在插件的底层 通过 SQL 语句分析命令:Explain 分析当前的 SQL 语句,根据结果集中的 Extra 列来断定当前是否全表操作。
添加插件
<!-- 注册执行分析插件 -->
<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
<property name="stopProceed" value="true"/> <!--是否停止-->
</bean>
- 参数:stopProceed 发现执行全表 delete update 语句是否停止执行
4.1 性能分析插件
com.baomidou.mybatisplus.plugins.PerformanceInterceptor
- 性能分析拦截器,用于输出每条 SQL 语句及其执行时间
- SQL 性能执行分析,开发环境使用,超过指定时间,停止运行。有助于发现问题
添加插件
<!-- 注册性能分析插件 -->
<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
<property name="format" value="true"/><!--格式化 SQL-->
<property name="maxTime" value="5"/><!--单位 ms-->
</bean>
或者
//Spring boot方式
@EnableTransactionManagement
@Configuration
@MapperScan("com.baomidou.cloud.service.*.mapper*")
public class MybatisPlusConfig {
/**
* SQL执行效率插件
*/
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
return new PerformanceInterceptor();
}
}
5.1 乐观锁插件
com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor
- 如果想实现如下需求: 当要更新一条记录的时候,希望这条记录没有被别人更新
- 乐观锁的实现原理:
- 取出记录时,获取当前 version 2
- 更新时,带上这个 version 2
- 执行更新时, set version = yourVersion+1 where version = yourVersion
- 如果 version 不对,就更新失败
- @Version 用于注解实体字段,必须要有
- 特别说明: 仅支持int,Integer,long,Long,Date,Timestamp
添加插件
<!-- 注册乐观锁插件 -->
<bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"/>
或者
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
示例SQL原理
update tbl_user set name='update',version=3 where id=100 and version=2;
6.1 XML文件热加载
开启动态加载 mapper.xml
- 多数据源配置多个 MybatisMapperRefresh 启动 bean
- 默认情况下,eclipse保存会自动编译,idea需自己手动编译一次
spring配置
<bean class="com.baomidou.mybatisplus.spring.MybatisMapperRefresh">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
<constructor-arg name="mapperLocations" value="classpath*:mybatis/mappers/*/*.xml"/>
<constructor-arg name="delaySeconds" value="10"/>
<constructor-arg name="sleepSeconds" value="20"/>
<constructor-arg name="enabled" value="true"/>
</bean>
参数说明
sqlSessionFactory:session工厂
mapperLocations:mapper匹配路径
enabled:是否开启动态加载 默认:false
delaySeconds:项目启动延迟加载时间 单位:秒 默认:10s
sleepSeconds:刷新时间间隔 单位:秒 默认:20s