一、Mybatis插件机制
mybatis通过插件(Interceptor)对相关目标对象(四大对象)进行动态代理,完成相关数据的变更,从而提供更多功能。
在这里不介绍其内部实现,仅仅介绍MP所提供的相关插件。
二、MP插件介绍
2.1、分页插件
好像MP已经在BaseMapper中提供了相关分页方法selectPage,为什么还要使用分页插件呢?
这是因为selectPage通过ibatis的RowBounds进行分页,也就是在内存中进行分页,所以不推荐
而分页插件的使用,是在相关的查询语句后面添加Limit关键字,从而实现物理分页
applicationContext.xml
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:mybatis-config.xml" /> <property name="typeAliasesPackage" value="cn.hjj.mp.entity"></property> <property name="globalConfig" ref="globalConfiguration"></property> <!-- 注入插件 --> <property name="plugins"> <list> <!-- 分页插件 --> <bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean> </list> </property> </bean>
测试代码如下
/** * 分页插件测试使用 */ @Test public void testPaginate() { Page<Employee> page = new Page<>(1, 3); List<Employee> emps = employeeMapper.selectPage(page, null); //FROM tbl_employee LIMIT 0,3 System.out.println(emps); System.out.println("==========获取分页相关信息============="); System.out.println("总条数:" + page.getTotal()); System.out.println("总页数:" + page.getPages()); System.out.println("当前页码:" + page.getCurrent()); System.out.println("每页显示条数:" + page.getSize()); System.out.println("是否有上一页:" + page.hasPrevious()); System.out.println("是否有下一页:" + page.hasNext()); //封装当前页数据到Page对象中 page.setRecords(emps); }
Page用于封装分页相关参数
2.2、执行分析插件
SQL的执行分析插件,目前只支持MYSQL5.6.3以上版本
该作用主要分析DELETE以及UPDATE的语句是否是进行全表操作。
本质是在SQL语句前面拼接Explain关键字,从而分析要执行的SQL语句
判断结果的Extra列来判断是否全表操作
applicationContext.xml
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:mybatis-config.xml" /> <property name="typeAliasesPackage" value="cn.hjj.mp.entity"></property> <property name="globalConfig" ref="globalConfiguration"></property> <!-- 注入插件 --> <property name="plugins"> <list> <!-- 执行分析插件 ,不推荐生产环境使用--> <bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor"> <!-- stopProceed 发现执行全表 delete update 语句是否停止执行 --> <property name="stopProceed" value="true"></property> </bean> </list> </property> </bean>
测试代码如下
/** * 执行分析插件测试使用 * 本质通过 Explain这个SQL关键字分析执行的SQL */ @Test(expected=Exception.class) public void testSqlExplain() { employeeMapper.delete(null); //全表删除 }
2.3、性能分析插件
主要用于输出SQL语句以及其执行时间,可以设置其超过指定时间,停止运行
不推荐生产环境中使用
applicationContext.xml
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:mybatis-config.xml" /> <property name="typeAliasesPackage" value="cn.hjj.mp.entity"></property> <property name="globalConfig" ref="globalConfiguration"></property> <!-- 注入插件 --> <property name="plugins"> <list> <!-- 性能分析插件 --> <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor"> <property name="format" value="true"></property> <!-- 设置最大执行时间,超过则报错,提示优化,但是SQL一样成功执行 --> <!-- <property name="maxTime" value="100000"></property> --> </bean> </list> </property> </bean>
2.4、乐观锁插件
乐观锁插件所要做的事情就是:
1、取出记录时,会带上当前版本version值
2、然后更新的时候会将自己的version值跟数据库记录的version值比较
如果相等,则执行更新操作,并将version+1;如果不等,则更新失败
其实实现的需求就是希望在更新记录的时候,希望这条记录没有给其他人更新过
注意:使用乐观锁插件,需要使用@Version注解实体字段,并且数据库中也要有对应映射字段
@TableName("tbl_employee") public class Employee extends Model<Employee> { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) private Integer id; private String lastName; private String email; private String gender; private Integer age; @Version private Integer version;
applicationContext.xml
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:mybatis-config.xml" /> <property name="typeAliasesPackage" value="cn.hjj.mp.entity"></property> <property name="globalConfig" ref="globalConfiguration"></property> <!-- 注入插件 --> <property name="plugins"> <list> <!-- 乐观锁插件 --> <bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"></bean> </list> </property> </bean>