1. 程式人生 > >MyBatis學習——第四篇(攔截器和攔截器分頁實現)

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:[email protected]
外掛方法2--將要包裝的目標物件2:[email protected]
當前頁碼:1
總記錄數:0
每頁的記錄數:10
總頁碼:0

外掛方法1--將要包裝的目標物件1:[email protected]67906
外掛方法2--將要包裝的目標物件2:[email protected]67906
外掛方法1--將要包裝的目標物件1:[email protected]3df68
外掛方法2--將要包裝的目標物件2:[email protected]3df68
外掛方法1--將要包裝的目標物件1:[email protected]995e
外掛方法2--將要包裝的目標物件2:[email protected]995e


攔截的物件是2:[email protected]3df68
攔截方法是2:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
攔截引數是2:1

攔截的物件是1:[email protected]3df68
攔截方法是1:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
攔截引數是1:1

外掛方法1--將要包裝的目標物件1:[email protected]2b668
外掛方法2--將要包裝的目標物件2:[email protected]2b668
外掛方法1--將要包裝的目標物件1:[email protected]5b38
外掛方法2--將要包裝的目標物件2:[email protected]5b38
外掛方法1--將要包裝的目標物件1:[email protected]2331b
外掛方法2--將要包裝的目標物件2:[email protected]2331b

攔截的物件是2:[email protected]5b38
攔截方法是2:public abstract java.util.List org.apache.ibatis.executor.resultset.ResultSetHandler.handleResultSets(java.sql.Statement) throws java.sql.SQLException
攔截引數是2:1

攔截的物件是1:[email protected]5b38
攔截方法是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]
---------結束---------