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
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!