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]
---------結束---------