mybatis mybatis-spring 源碼流程分析

前言

實際項目中通常使用mybatis-spring獲得mapper的bean對象压汪。本文通過 mybatis 和 mybatis-spring 的源碼流程 了解其實現(xiàn)方式勃痴。

mybatis-logo

mybatis doc

http://www.mybatis.org/mybatis-3/zh/getting-started.html

mybatis-spring doc

http://www.mybatis.org/spring/zh/index.html

mybatis-spring github

https://github.com/mybatis/spring


mybatis 源碼流程

session & binding

SqlSession session = sqlSessionFactory.openSession();
try {
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  Blog blog = mapper.selectBlog(101);
} finally {
  session.close();
}

第一部分:構(gòu)造sessionFactory

第二部分 查詢

    1. sqlsession.getMapper() 返回的是接口的 動態(tài)代理 MapperProxy
    1. 接口調(diào)用時 MapperProxy.invoke()調(diào)用潮改,根據(jù)方法名獲取MapperMethod
    1. 執(zhí)行MapperMethod.execute() 根據(jù)mapper標簽區(qū)分CRUD操作烤咧,調(diào)用sqlSession。

transaction

    1. Transaction接口 包裝了connection, 管理其聲明周期酪耳,創(chuàng)建浓恳,提交,回滾葡兑,關(guān)閉奖蔓。
    1. 有兩種實現(xiàn), JDBC事務(wù) 和 Managed交由spring處理讹堤。

datasource

    1. POOLED 帶連接池的 數(shù)據(jù)源
      PooledDataSource.getconnection() 調(diào)用popConnection()從空閑連接中獲取PooledConnection對象。
      如果idleConnections非空厨疙,直接取其中的一個返回洲守。
      如果activeConnections 活躍連接數(shù)小于 配置的上限,則創(chuàng)建一個新的連接返回沾凄。
      如果無可用連接梗醇,等待后再次獲取。
      最后 獲取將準備返回的conn記錄到activeConnections中撒蟀。

PooledConnection是Connection的一個動態(tài)代理叙谨。主要為了在調(diào)用connection對象的接口前,檢查連接是否過期保屯。另外手负,如果調(diào)用close涤垫,會將connect歸還連接池。

    1. UNPOOLED 不帶連接池 的數(shù)據(jù)源
      UnpooledDataSource.getconnection() 使用JDBC API 從 DriverManager獲取連接竟终。
      PooledDataSource也是通過UnpooledDataSource獲取底層的連接蝠猬。

plugin

// ExamplePlugin.java
@Intercepts({@Signature(
  type= Executor.class,
  method = "update",
  args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
  public Object intercept(Invocation invocation) throws Throwable {
    return invocation.proceed();
  }
  public Object plugin(Object target) {
    return Plugin.wrap(target, this);
  }
  public void setProperties(Properties properties) {
  }
}
    1. 實現(xiàn)Interceptor 接口,并通過Intercepts注解 指明需要攔截的方法统捶∮苈可以攔截 Executor ,ParameterHandler 喘鸟,ResultSetHandler 匆绣,StatementHandler 的方法。
    1. 解析配置文件時什黑,解析plugin標簽崎淳,生成一個攔截器的列表 InterceptorChain對象。
    1. 通過Configuration工廠方法 newExecutor newStatementHandler newParameterHandler newResultSetHandler 中會 通過 interceptorChain.pluginAll 應(yīng)用所有攔截器兑凿,得到代理后的對象凯力。供后續(xù)流程使用。 pluginall迭代調(diào)用所有插件的plugin方法礼华。
    1. Plugin提供工具方法wrap用于咐鹤,生成傳入對象的動態(tài)代理。 第一個參數(shù)為 被代理對象圣絮。第二個參數(shù)為 Interceptor (plugin)對象本身祈惶。
    1. 當(dāng)攔截方法調(diào)用時,會執(zhí)行Interceptor的intercept方法扮匠,傳入的Invocation 對象 封裝了代理方法的調(diào)用過程捧请,通過調(diào)用proceed方法 使之執(zhí)行。

binding

生成mapper接口的 動態(tài)代理棒搜。
實現(xiàn)方式與 retrofit 相同疹蛉。 http://www.reibang.com/p/122859d42f4f

    1. MapperProxyFactory<T> 用于生成mapper的動態(tài)代理對象。
    1. MapperProxy<T> mapper的動態(tài)代理力麸。保存了接口中的所有方法map methodCache可款。
@Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, args);
      } else if (isDefaultMethod(method)) {
        return invokeDefaultMethod(proxy, method, args);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
    final MapperMethod mapperMethod = cachedMapperMethod(method);
    return mapperMethod.execute(sqlSession, args);
  }

接口調(diào)用時invoke根據(jù)傳入的method 在methodCache中查找方法,調(diào)用MapperMethod.execute()

    1. MapperMethod 根據(jù) interface method 到configuration中找到MappedStatement克蚂。根據(jù)MappedStatement的類型闺鲸,query,insert,update,delete 在execute時 將方法路由到sqlsession 相應(yīng)的實現(xiàn)上。

executor

sql的執(zhí)行器埃叭,封裝了對jdbc的調(diào)用摸恍。
sqlsession調(diào)用executor實現(xiàn) 對底層sql的執(zhí)行。

    1. statement 子包赤屋, 封裝了jdbc Statement 對象 的執(zhí)行立镶。StatementHandler接口壁袄。

mybatis-spring 源碼流程

    1. SqlSessionTemplate類
      線程安全的SqlSession實現(xiàn)
      使用內(nèi)部類SqlSessionInterceptor作為動態(tài)代理,invoke調(diào)用時
      首先從事務(wù)管理器獲取sqlsession谜慌,如果是在一個事務(wù)中則sql是ThreadLocal中存儲的sqlsession然想。
      如果不在事務(wù)中,則通過sqlSessionFactory.openSession()新創(chuàng)建一個sqlsession對象欣范。
      最后調(diào)用registerSessionHolder(sqlsession) , 如果開啟事務(wù)变泄,將sqlsession注冊。

transaction

實現(xiàn)mybatis包中的事務(wù)接口恼琼, 提供 spring 管理的 事務(wù)妨蛹。
使用了 spring-jdbc spring-tx

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晴竞,隨后出現(xiàn)的幾起案子蛙卤,更是在濱河造成了極大的恐慌,老刑警劉巖噩死,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颤难,死亡現(xiàn)場離奇詭異,居然都是意外死亡已维,警方通過查閱死者的電腦和手機行嗤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來垛耳,“玉大人栅屏,你說我怎么就攤上這事√孟剩” “怎么了栈雳?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長缔莲。 經(jīng)常有香客問我哥纫,道長,這世上最難降的妖魔是什么痴奏? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任磺箕,我火速辦了婚禮,結(jié)果婚禮上抛虫,老公的妹妹穿的比我還像新娘。我一直安慰自己简僧,他們只是感情好建椰,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著岛马,像睡著了一般棉姐。 火紅的嫁衣襯著肌膚如雪屠列。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天伞矩,我揣著相機與錄音笛洛,去河邊找鬼。 笑死乃坤,一個胖子當(dāng)著我的面吹牛苛让,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播湿诊,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼狱杰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了厅须?” 一聲冷哼從身側(cè)響起仿畸,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎朗和,沒想到半個月后错沽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡眶拉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年千埃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镀层。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡镰禾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出唱逢,到底是詐尸還是另有隱情吴侦,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布坞古,位于F島的核電站备韧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏痪枫。R本人自食惡果不足惜织堂,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望奶陈。 院中可真熱鬧易阳,春花似錦、人聲如沸吃粒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至事示,卻和暖如春早像,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肖爵。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工卢鹦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人劝堪。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓冀自,卻偏偏與公主長得像,于是被迫代替她去往敵國和親幅聘。 傳聞我的和親對象是個殘疾皇子凡纳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容