上一節咱們學習了mybatis-plus
的代碼生成器
,這一節咱們來學習一下mybatis-plus
的插件拓展
。java
首先咱們來複習一下Mybatis 插件機制:mysql
- 插件機制: Mybatis 經過插件(Interceptor) 能夠作到攔截四大對象相關方法的執行,根據需求, 完成相關數據的動態改變。 Executor StatementHandler ParameterHandler ResultSetHandler
- 插件原理: 四大對象的每一個對象在建立時,都會執行 interceptorChain.pluginAll(),會通過每一個插件對象的 plugin()方法,目的是爲當前的四大對象建立代理。代理對象就能夠攔截到四大對象相關方法的執行,由於要執行四大對象的方法須要通過代理。
咱們在mybatis-plus
這裏學習三個插件,其餘的插件看官能夠本身自行嘗試:git
首先按照快速開始——Spring集成Mybatis-Plus
一節的操做,新建一個mp06
的 Module
,能夠將mp05
中的內容所有複製過來。github
修改mp06的pom.xml文件:web
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mybatis-plus-in-action</artifactId>
<groupId>com.demo.mybatis-plus</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mp06</artifactId>
<dependencies>
<!-- mp 依賴
mybatis-plus 會自動維護mybatis 以及 mybatis-spring相關的依賴
Mybatis 及 Mybatis-Spring 依賴請勿加入項目配置,以避免引發版本衝突!!!Mybatis-Plus 會自動幫你維護!
-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>${mybatis.plus.version}</version>
</dependency>
<!--junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!--lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--注意: MyBatis-Plus 從 3.0.3 以後移除了代碼生成器與模板引擎的默認依賴,須要手動添加相關依賴: -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis.plus.version}</version>
</dependency>
<!--模板引擎
MP 的代碼生成器默認使用的是 Apache 的 Velocity 模板,固然也能夠更換爲別的模板
技術,例如 freemarker。此處不作過多的介紹。
須要加入 Apache Velocity 的依賴-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!--加入 slf4j ,查看日誌輸出信息-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
</project>
複製代碼
下面咱們須要根據不一樣的插件作的一些修改:spring
其實在以前的分頁查詢代碼示例中,咱們已經展現了分頁插件,不過當時並無介紹,如今咱們來詳細介紹一下。sql
咱們有兩種配置方式能夠實現分頁的功能:數據庫
<!-- 一、第一種方式,在 mybatis-config.xml 文件中引入分頁插件-->
<plugins>
<plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></plugin>
</plugins>
複製代碼
完整mybatis-config.xml
文件以下:apache
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 一、第一種方式,在 mybatis-config.xml 文件中引入分頁插件-->
<plugins>
<plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></plugin>
</plugins>
</configuration>
複製代碼
在sqlSessionFactory
這個bean中,經過<property name="plugins">
配置插件,接下來的全部插件都配置在這個list中api
<!-- 二、第二種方式,在 applicationContext.xml 文件中引入分頁插件-->
<property name="plugins">
<list>
<!-- 分頁查詢插件 -->
<bean id="paginationInterceptor"
class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
<property name="dialectType" value="mysql"/>
</bean>
</list>
</property>
複製代碼
1.1和1.2的方式選擇哪種均可以實現分頁的功能,如今咱們在 TestMp
測試類中添加下面代碼,來測試分頁插件的功能
/**
* 測試分頁插件
*/
@Test
public void testPage() {
IPage<Employee> employeeIPage = employeeMapper.selectPage(new Page<>(2, 1), null);
System.out.println("employeeIPage:" + employeeIPage.getRecords());
}
複製代碼
該插件的做用是分析 DELETE UPDATE 語句,防止小白或者惡意進行 DELETE UPDATE 全表操做 。在插件的底層 經過 SQL 語句分析命令:Explain 分析當前的 SQL 語句, 根據結果集中的 Extra 列來判定當前是否全表操做。
注意
:只建議在開發環境中使用,不建議在生產環境使用 。SQL 執行分析攔截器,只支持 MySQL5.6.3 以上版本 。
<!-- 執行分析插件 只建議在開發環境中使用,不建議在生產環境使用 -->
<bean class="com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor">
<property name="sqlParserList">
<!-- 禁止全表刪除-->
<bean class="com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser"></bean>
</property>
</bean>
複製代碼
咱們來進行一個全表刪除來測試一下咱們的執行分析插件,在測試類中添加下面的代碼:
/**
* 測試 SQL 執行分析插件
*/
@Test
public void testSqlExplain() {
// 全表刪除
employeeMapper.delete(null);
}
複製代碼
執行該方法後咱們會看到測試方法執行失敗,提示咱們禁止全表的刪除:
思考?若是想實現以下需求: 當要更新一條記錄的時候,但願這條記錄沒有被別人更新 。當咱們想實現上面的需求的時候,首先想到的是使用樂觀鎖機制。
樂觀鎖的實現原理: 1)取出記錄時,獲取當前 version 2)更新時,帶上這個 version 3)執行更新時, set version = yourVersion+1 where version = yourVersion 若是 version 不對,就更新失敗
要想使用Mybatis-Plus
提供的樂觀鎖插件,首先須要修改applicationContext.xml文件,添加樂觀鎖插件
<!-- 樂觀鎖插件,作這個測試的時候,須要給實體類接一個version字段,相應的也須要在數據庫中添加該字段 -->
<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"></bean>
複製代碼
修改Employee實體類,添加 version
字段,並添加getter、setter方法
@Version
private Integer version;
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
複製代碼
在測試類中添加下面的代碼:
/**
* 測試 樂觀鎖
*/
@Test
public void testOptimisticLocker() {
Employee employee = new Employee();
employee.setId(10);
employee.setLastName("MP");
employee.setAge(25);
employee.setEmail("mp@qq.com");
employee.setGender("0");
employee.setVersion(2);
![mp06-02.png](https://upload-images.jianshu.io/upload_images/19878305-e8348cc75321c5f1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
employeeMapper.updateById(employee);
}
複製代碼
執行該方法後咱們會看到測試方法執行成功,更新時,帶上這個 version,但更新的數據爲0條,表示數據庫中的數據並無被更新,注意看咱們的更新代碼:
完成上面的操做後,mp06的完整applicationContext.xml
文件以下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring
http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- 數據源 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource"
class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 事務管理器 -->
<bean id="dataSourceTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 基於註解的事務管理 -->
<tx:annotation-driven
transaction-manager="dataSourceTransactionManager"/>
<!-- 配置 SqlSessionFactoryBean
mybatis提供的:org.mybatis.spring.SqlSessionFactoryBean
mybatis-plus提供的:3.2.0 com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean
2.3 com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
-->
<bean id="sqlSessionFactoryBean"
class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<!-- 數據源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 別名處理 -->
<property name="typeAliasesPackage" value="com.mp.beans"></property>
<!-- 注入配置-->
<!--<property name="configuration" ref="configuration"></property>-->
<!-- 注入全局配置策略-->
<property name="globalConfig" ref="globalConfiguration"></property>
<!-- 二、第二種方式,在 applicationContext.xml 文件中引入分頁插件-->
<property name="plugins">
<list>
<!-- 分頁查詢插件 -->
<bean id="paginationInterceptor"
class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
<property name="dialectType" value="mysql"/>
</bean>
<!-- 執行分析插件 只建議在開發環境中使用,不建議在生產環境使用 -->
<bean class="com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor">
<property name="sqlParserList">
<!-- 禁止全表刪除-->
<bean class="com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser"></bean>
</property>
</bean>
<!-- 樂觀鎖插件,作這個測試的時候,須要給實體類接一個version字段,相應的也須要在數據庫中添加該字段 -->
<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"></bean>
</list>
</property>
</bean>
<!--這個等於Mybatis的全局配置文件,若是在MybatisSqlSessionFactoryBean裏面已經配置了configLocation屬性(外部加載Mybatis全局配置文件),就不能再配置configuration屬性-->
<bean id="configuration" class="com.baomidou.mybatisplus.core.MybatisConfiguration">
<!--開啓駝峯命名-->
<property name="mapUnderscoreToCamelCase" value="true"/>
<!--日誌打印SQL語句-->
<property name="logImpl" value="org.apache.ibatis.logging.log4j.Log4jImpl"></property>
</bean>
<!-- 定義mybatis-plus全局策略配置-->
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
<!-- 全局主鍵策略-->
<property name="dbConfig" ref="dbConfig"></property>
</bean>
<!-- 這裏-->
<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
<!-- 全局表主鍵生成策略 -->
<property name="idType" value="AUTO"></property>
<!-- 全局的表前綴策略配置 -->
<property name="tablePrefix" value="tbl_"></property>
</bean>
<!--
配置 mybatis 掃描 mapper 接口的路徑
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage"
value="com.mp.mapper"></property>
</bean>
</beans>
複製代碼
mp06的代碼結構以下所示:
至此,基於 mybatis-plus
的插件拓展
演示就完成了,下面咱們就能夠進入到下一節自定義全局操做和全局sql注入
的學習了。
相關示例完整代碼:mybatis-plus-in-action