1. 程式人生 > >Mybatis的SqlSession運行廣東幸運28源碼出售原理

Mybatis的SqlSession運行廣東幸運28源碼出售原理

select 覆蓋 perm and 聯系 朋友 原理 建議 之前

SqlSession是Mybatis最重要廣東幸運28源碼出售(www.1159880099.com)QQ1159880099的構建之一,可以簡單的認為Mybatis一系列的配置目的是生成類似 JDBC生成的Connection對象的SqlSession對象,這樣才能與數據庫開啟“溝通”,通過SqlSession可以實現增刪改查(當然現在更加推薦是使用Mapper接口形式),那麽它是如何執行實現的,這就是本篇博文所介紹的東西,其中會涉及到簡單的源碼講解。

  了解SqlSession的運作原理是學習Mybatis插件的必經之路,因為Mybatis的插件會在SqlSession運行過程中“插入”運行,如果沒有很好理解的話,Mybatis插件可能會覆蓋相應的源碼造成嚴重的問題。鑒於此,本篇博文盡量詳細介紹SqlSession運作原理!

  建議:在我之前的博文《Mybatis緩存(1)--------系統緩存及簡單配置介紹》中介紹到SqlSession的產生過程,可以先理解後再讀此博文可能會更加好理解!

  註:本篇博文也是我最近真正理解Mybatis才開始編寫的,可能有些地方不太準確,如果有錯誤之處敬請指出,另外創作不易,望轉載告之,謝謝!

  參數資料:《深入淺出Mybatis基礎原理與實踐》(我這裏只有電子版PDF,需要的朋友可以聯系我)

1、SqlSession簡單介紹
  (1)SqlSession簡單原理介紹

  SqlSession提供select/insert/update/delete方法,在舊版本中使用使用SqlSession接口的這些方法,但是新版的Mybatis中就會建議使用Mapper接口的方法。

  映射器其實就是一個動態代理對象,進入到MapperMethod的execute方法就能簡單找到SqlSession的刪除、更新、查詢、選擇方法,從底層實現來說:通過動態代理技術,讓接口跑起來,之後采用命令模式,最後還是采用了SqlSession的接口方法(getMapper()方法等到Mapper)執行SQL查詢(也就是說Mapper接口方法的實現底層還是采用SqlSession接口方法實現的)。

  註:以上雖然只是簡單的描述,但實際上源碼相對復雜,下面將結合源碼進行簡單的介紹!

  (2)SqlSession重要的四個對象

    1)Execute:調度執行StatementHandler、ParmmeterHandler、ResultHandler執行相應的SQL語句;

    2)StatementHandler:使用數據庫中Statement(PrepareStatement)執行操作,即底層是封裝好了的prepareStatement;

    3)ParammeterHandler:處理SQL參數;

    4)ResultHandler:結果集ResultSet封裝處理返回。

2、SqlSession四大對象
(1)Execute執行器:
  執行器起到至關重要的作用,它是真正執行Java與數據庫交互的東西,參與了整個SQL查詢執行過程中。

1)主要有三種執行器:簡易執行器SIMPLE(不配置就是默認執行器)、REUSE是一種重用預處理語句、BATCH批量更新、批量專用處理器

復制代碼
package org.apache.ibatis.session;

/**

  • @author Clinton Begin
    */
    public enum ExecutorType {
    SIMPLE, REUSE, BATCH
    }
    復制代碼
    2)執行器作用:Executor會先調用StatementHandler的prepare()方法預編譯SQL語句,同時設置一些基本的運行參數,然後調用parameterize()方法啟用ParemeterHandler設置參數,完成預編譯,簡單總結起來就是即先預編譯SQL語句,之後設置參數

首先,以SimpleExecutor為例,查看源碼我們得到如下幾點重要知識點:

第一:Executor通過Configuration對象中newExecutor()方法中選擇相應的執行器生成

復制代碼
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
復制代碼
(註:最後interceptorChain.pluginAll()中執行層層動態代理,最後在可以在調用真正的Executor前可以修改插件代碼,這也就是為什麽學會Mybatis的插件必須要知道SqlSession的運行過程)

第二:在執行器中StatementHandler是根據Configuration構建的

復制代碼
public SimpleExecutor(Configuration configuration, Transaction transaction) {
super(configuration, transaction);
}

@Override
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
Statement stmt = null;
try {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
stmt = prepareStatement(handler, ms.getStatementLog());
return handler.update(stmt);
} finally {
closeStatement(stmt);
}
}
復制代碼
第三:Executor會執行StatementHandler的prepare()方法進行預編譯---->填入connection對象---->再調用parameterize()方法設置參數---->完成預編譯

復制代碼
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
Statement stmt;
Connection connection = getConnection(statementLog);
stmt = handler.prepare(connection, transaction.getTimeout());
handler.parameterize(stmt);
return stmt;
}
復制代碼
  總結以上繪制簡單思維圖如下:

(2)StatementHanlder數據庫會話器
      由Executor的prepareStatement方法中parameterize方法引出StatementHandler

      StatementHandler的生成是由Configuration方法中newStatementHandler()方法生成的,但是StatementHandler是RoutingStatementHandler

復制代碼
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject,
                               RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
return statementHandler;
}
復制代碼

Mybatis的SqlSession運行廣東幸運28源碼出售原理