MyBatis學習——第四篇(攔截器和攔截器分頁實現)

MyBatis架構體圖


1:mybatis核心對象
從MyBatis代碼實現的角度來看,MyBatis的主要的核心部件有以下幾個:

SqlSession            作爲MyBatis工作的主要頂層API,表示和數據庫交互的會話,完成必要數據庫增刪改查功能
Executor              MyBatis執行器,是MyBatis 調度的核心,負責SQL語句的生成和查詢緩存的維護
StatementHandler   封裝了JDBC Statement操作,負責對JDBC statement 的操作,如設置參數、將Statement結果集轉換成List集合。
ParameterHandler   負責對用戶傳遞的參數轉換成JDBC Statement 所需要的參數,
ResultSetHandler    負責將JDBC返回的ResultSet結果集對象轉換成List類型的集合;
TypeHandler          負責java數據類型和jdbc數據類型之間的映射和轉換
MappedStatement   MappedStatement維護了一條<select|update|delete|insert>節點的封裝, 
SqlSource            負責根據用戶傳遞的parameterObject,動態地生成SQL語句,將信息封裝到BoundSql對象中,並返回
BoundSql             表示動態生成的SQL語句以及相應的參數信息
Configuration        MyBatis所有的配置信息都維持在Configuration對象之中。
它們的關係如下圖所示:

如果想要對這四大對象進行操作可以用插件實現攔截操作,故插件就是攔截器

它們都是sqlSession的底層類實現,也是插件能夠攔截的四大對象。所以這裏已經觸及了MyBATIS的底層,動態代理,反射隨時可以看到。瞭解他們的協作,是插件編寫的基礎之一,所以這是十分的重要。

 

2:mybatis攔截器
第一步首先在Mybatis配置文件中配置攔截器插件

    <!--配置插件  -->
    <plugins>
        <plugin interceptor="com.thit.interceptor.Myinterceptor1">
            <property name="shuxing1" value="value1"/>
            <property name="shuxing2" value="value11"/>
        </plugin>
        <plugin interceptor="com.thit.interceptor.Myinterceptor2">
            <property name="shuxing1" value="value2"/>
            <property name="shuxing2" value="value22"/>
        </plugin>
        <!-- com.github.pagehelper爲PageHelper類所在包名 ,pagehelper分頁工具-->
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- 使用下面的方式配置參數,後面會有所有的參數介紹 -->
            <property name="param1" value="value1"/>
        </plugin>
    </plugins>
然後創建這兩個攔截器:

攔截器1代碼如下

package com.thit.interceptor;
 
import java.sql.Statement;
import java.util.Properties;
 
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
 
 
import org.apache.ibatis.plugin.Intercepts;
/**
 * 
 * @author 79027
 * 插件簽名,告訴mybatis插件用來攔截那個對象的那個方法
 */
@Intercepts({
    @Signature(type=ResultSetHandler.class,method="handleResultSets",args=Statement.class)
})
 
public class Myinterceptor1 implements Interceptor{
    //攔截目標對象
    public Object intercept(Invocation invocation) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("攔截的對象是1:"+invocation.getTarget());
        System.out.println("攔截方法是1:"+invocation.getMethod().toString());
        System.out.println("攔截參數是1:"+invocation.getArgs().length);
        //執行攔截對象真正的方法
        Object o=invocation.proceed();
        return o;
    }
    //包裝目標對象 爲目標對象創建動態代理
    public Object plugin(Object target) {
        // TODO Auto-generated method stub
        System.out.println("插件方法1--將要包裝的目標對象1:"+target);
        //爲當前對象創建代理對象
        Object o=Plugin.wrap(target, this);
        return o;
    }
    //獲取插件初始化參數
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub
        String value1=(String) properties.get("shuxing1");    
        String value2=(String) properties.get("shuxing2");
        System.out.println("插件初始化參數1:"+value1+":"+value2);
    }
 
}
攔截器2代碼如下:

package com.thit.interceptor;
 
import java.sql.Statement;
import java.util.Properties;
 
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
 
 
import org.apache.ibatis.plugin.Intercepts;
/**
 * 
 * @author 79027
 * 插件簽名,告訴mybatis插件用來攔截那個對象的那個方法
 */
@Intercepts({
    @Signature(type=ResultSetHandler.class,method="handleResultSets",args=Statement.class)
})
 
public class Myinterceptor2 implements Interceptor{
    //攔截目標對象 多個插件的時候按照    從後到前的順序執行
    public Object intercept(Invocation invocation) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("攔截的對象是2:"+invocation.getTarget());
        System.out.println("攔截方法是2:"+invocation.getMethod().toString());
        System.out.println("攔截參數是2:"+invocation.getArgs().length);
        //執行攔截對象真正的方法
        Object o=invocation.proceed();
        return o;
    }
    //包裝目標對象 爲目標對象創建動態代理 按照從前到後的順序執行
    public Object plugin(Object target) {
        // TODO Auto-generated method stub
        System.out.println("插件方法2--將要包裝的目標對象2:"+target);
        //爲當前對象創建代理對象
        Object o=Plugin.wrap(target, this);
        return o;
    }
    //獲取插件初始化參數
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub
        String value1=(String) properties.get("shuxing1");    
        String value2=(String) properties.get("shuxing2");
        System.out.println("插件初始化參數2:"+value1+":"+value2);
    }
 
}
最後測試代碼如下:
        void getAllpersion1() {
            System.out.println("--------查詢全部---------");
            SqlSession sqlSession = dbtools.getSession();
            PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);
            //分頁
            //第二種,Mapper接口方式的調用,推薦這種使用方式。
             Page<Object> page=PageHelper.startPage(1, 10);
              System.out.println("當前頁碼:"+page.getPageNum());
                System.out.println("總記錄數:"+page.getTotal());
                System.out.println("每頁的記錄數:"+page.getPageSize());
                System.out.println("總頁碼:"+page.getPages());
            
            List<Person> list=personMapper.getAllPersons();
            System.out.println("集合長度:"+list.size());
            PageInfo pageinfo=new PageInfo(list);
            
            System.out.println("pageinfo總條數:"+pageinfo.getTotal());
            System.out.println("pageinfo每頁的記錄數:"+pageinfo.getPageSize());
            System.out.println("pageinfo總頁碼:"+pageinfo.getPageNum());
            System.out.println("pageinfo總頁碼:"+pageinfo.getPages());
            
            for(Person p:list) {
                System.out.println(p);
            }
            System.out.println("---------結束---------");
    
        }
        
        
通過測試代碼的輸出結果,我麼可以看到

插件初始化參數1:value1:value11
插件初始化參數2:value2:value22


插件方法1--將要包裝的目標對象1:org.apache.ibatis.executor.CachingExecutor@6f7fd0e6
插件方法2--將要包裝的目標對象2:org.apache.ibatis.executor.CachingExecutor@6f7fd0e6
當前頁碼:1
總記錄數:0
每頁的記錄數:10
總頁碼:0

插件方法1--將要包裝的目標對象1:org.apache.ibatis.scripting.defaults.DefaultParameterHandler@72967906
插件方法2--將要包裝的目標對象2:org.apache.ibatis.scripting.defaults.DefaultParameterHandler@72967906
插件方法1--將要包裝的目標對象1:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@4f83df68
插件方法2--將要包裝的目標對象2:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@4f83df68
插件方法1--將要包裝的目標對象1:org.apache.ibatis.executor.statement.RoutingStatementHandler@7d8995e
插件方法2--將要包裝的目標對象2:org.apache.ibatis.executor.statement.RoutingStatementHandler@7d8995e


攔截的對象是2:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@4f83df68
攔截方法是2:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
攔截參數是2:1

攔截的對象是1:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@4f83df68
攔截方法是1:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
攔截參數是1:1

插件方法1--將要包裝的目標對象1:org.apache.ibatis.scripting.defaults.DefaultParameterHandler@5b12b668
插件方法2--將要包裝的目標對象2:org.apache.ibatis.scripting.defaults.DefaultParameterHandler@5b12b668
插件方法1--將要包裝的目標對象1:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@1165b38
插件方法2--將要包裝的目標對象2:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@1165b38
插件方法1--將要包裝的目標對象1:org.apache.ibatis.executor.statement.RoutingStatementHandler@4c12331b
插件方法2--將要包裝的目標對象2:org.apache.ibatis.executor.statement.RoutingStatementHandler@4c12331b

攔截的對象是2:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@1165b38
攔截方法是2:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
攔截參數是2:1

攔截的對象是1:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@1165b38
攔截方法是1:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
攔截參數是1:1

集合長度:10
pageinfo總條數:144
pageinfo每頁的記錄數:10
pageinfo總頁碼:1
pageinfo總頁碼:15
Person [id=1, username=tom, [email protected], gender=F, dept=null]
Person [id=2, username=tom, [email protected], gender=F, dept=null]
Person [id=3, username=tom, [email protected], gender=F, dept=null]
Person [id=4, username=tom, [email protected], gender=F, dept=null]
Person [id=5, username=tom, [email protected], gender=F, dept=null]
Person [id=6, username=tom, [email protected], gender=F, dept=null]
Person [id=7, username=tom, [email protected], gender=F, dept=null]
Person [id=8, username=tom, [email protected], gender=F, dept=null]
Person [id=9, username=tom, [email protected], gender=F, dept=null]
Person [id=10, username=tom, [email protected], gender=F, dept=null]
---------結束---------
--------------------- 
作者:淺水壁虎 
來源:CSDN 
原文:https://blog.csdn.net/huyiju/article/details/82454735 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章