一、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>