1. 程式人生 > >MyBatis四大物件

MyBatis四大物件

mybatis四大物件指的是:executor,statementHandler,parameterHandler和resultHandler物件。這四個物件在sqlSession內部共同協作完成sql語句的執行,同時也是我們自定義外掛攔截的四大物件。

1、 Executor

sqlSession 首先會呼叫executor.query方法執行查詢。

Executor有以下四種(均繼承了BaseExecutor,可在spring檔案bean中配置):
SimpleExecutor-簡單的Executor,所有的資料庫操作均委託給StatementHandler處理
BatchExecutor - 批量更新的Executor,使用jdbc的batchupdate方法,使用此Executor,需要手動執行SqlSession的flushStatements,立即執行sql。
ReuseExecutor-大體上與SimpleExecutor相同,只是根據sql快取了jdbc的statement,遇到相同的sql時,省去了statement的建立,提高效率,但需要手動執行SqlSession的flushStatements,清除快取
CachingExecutor - 在mapper中配置cache,對查詢結果做快取,其中快取的key根據以下程式碼存數生成,建議最好不要用mybatis這個層次的快取,一般業務層的快取更實用,而且更容易控制

mybatis生產Executor的關鍵程式碼如下:

public Object pluginAll(Object target) {  
    for (Interceptor interceptor : interceptors) {  
      target = interceptor.plugin(target);  
    }  
    return target;  
  }  

此處採用責任鏈與JDK動態代理模式結合的方式,遍歷的Interceptor 即遍歷mybatis的攔截器。責任鏈模式可理解為若干攔截器物件組成一條攔截連結串列,請求在這個攔截連結串列一直傳遞,直到鏈上的某一攔截器物件處理此請求,這一模式在servlet的Filter和Dubbo的Filter有用到。不同的是,mybatis責任鏈則是通過動態代理的方式,使用Plugin代理實際的Executor類,即plugin(plugin(…(executor)))。

public class Plugin implements InvocationHandler{
    private Object target;
    private Interceptor interceptor;
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {      
        if (滿足代理條件) {
            return interceptor.intercept(new Invocation(target, method, args));
        }
        return
method.invoke(target, args); } //對傳入的物件進行代理,可能是實際的Executor類,也可能是Plugin代理類 public static Object wrap(Object target, Interceptor interceptor) { Class<?> type = target.getClass(); Class<?>[] interfaces = getAllInterfaces(type, signatureMap); if (interfaces.length > 0) { return Proxy.newProxyInstance( type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)); } return target; } }

2、StatementHandler

Executor在doQuery時生成StatementHandler物件
在MyBatis實現了statementHandler的有四個類:
RoutingStatementHandler,這是一個封裝類,它不提供具體的實現,只是根據Executor的型別,建立不同的型別StatementHandler。
SimpleStatementHandler,這個類對應於JDBC的Statement物件,用於沒有預編譯引數的SQL的執行。
PreparedStatementHandler 這個用於預編譯引數SQL的執行。
CallableStatementHandler 它將實儲存過程的排程。

statementHandler的主要方法:
prepare:編譯sql
parameterize:prepare後設置引數
query/update:sql執行

基於StatementHandler物件定義的外掛:
修改sql語句則在預編譯SQL(prepare方法前)操作。
修改引數則在呼叫parameterize方法前修改邏輯。或者使用ParameterHandler來改造設定引數。
組裝結果集則在query方法前後加入邏輯,或者使用ResultHandler來改造組裝結果。