7、插件拓展

上一節咱們學習了mybatis-plus 的代碼生成器,這一節咱們來學習一下mybatis-plus 的插件拓展java

首先咱們來複習一下Mybatis 插件機制:mysql

  1. 插件機制: Mybatis 經過插件(Interceptor) 能夠作到攔截四大對象相關方法的執行,根據需求, 完成相關數據的動態改變。 Executor StatementHandler ParameterHandler ResultSetHandler
  2. 插件原理: 四大對象的每一個對象在建立時,都會執行 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

咱們有兩種配置方式能夠實現分頁的功能:數據庫

1.一、修改mybatis-config.xml文件,添加分頁插件

<!-- 一、第一種方式,在 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>
複製代碼

1.二、修改applicationContext.xml文件,添加分頁插件

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和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 以上版本 。

2.二、修改applicationContext.xml文件,添加執行分析插件

<!-- 執行分析插件 只建議在開發環境中使用,不建議在生產環境使用 -->
<bean class="com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor">
    <property name="sqlParserList">
        <!-- 禁止全表刪除-->
        <bean class="com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser"></bean>
    </property>
</bean>
複製代碼

2.二、測試執行分析插件

咱們來進行一個全表刪除來測試一下咱們的執行分析插件,在測試類中添加下面的代碼:

/**
* 測試 SQL 執行分析插件
*/
@Test
public void testSqlExplain() {

    // 全表刪除
    employeeMapper.delete(null);
}
複製代碼

執行該方法後咱們會看到測試方法執行失敗,提示咱們禁止全表的刪除:

mp06-01.png

三、樂觀鎖插件

思考?若是想實現以下需求: 當要更新一條記錄的時候,但願這條記錄沒有被別人更新 。當咱們想實現上面的需求的時候,首先想到的是使用樂觀鎖機制。

樂觀鎖的實現原理: 1)取出記錄時,獲取當前 version 2)更新時,帶上這個 version 3)執行更新時, set version = yourVersion+1 where version = yourVersion 若是 version 不對,就更新失敗

3.一、修改applicationContext.xml文件,添加樂觀鎖插件

要想使用Mybatis-Plus提供的樂觀鎖插件,首先須要修改applicationContext.xml文件,添加樂觀鎖插件

<!-- 樂觀鎖插件,作這個測試的時候,須要給實體類接一個version字段,相應的也須要在數據庫中添加該字段 -->
<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"></bean>
複製代碼

3.二、修改Employee實體類

修改Employee實體類,添加 version 字段,並添加getter、setter方法

@Version
private Integer version;

public Integer getVersion() {
    return version;
}

public void setVersion(Integer version) {
    this.version = version;
}
複製代碼

3.三、測試樂觀鎖插件

在測試類中添加下面的代碼:

/**
* 測試 樂觀鎖
*/
@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-02.png

完成上面的操做後,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的代碼結構以下所示:

mp06-03.png

至此,基於 mybatis-plus 的插件拓展演示就完成了,下面咱們就能夠進入到下一節自定義全局操做和全局sql注入的學習了。

源代碼

相關示例完整代碼:mybatis-plus-in-action

相關文章
相關標籤/搜索