前言
Java程序員以前連接數(shù)據(jù)庫(kù)是這樣的
現(xiàn)在連接數(shù)據(jù)庫(kù)是這樣的
在傳統(tǒng)的JDBC 實(shí)現(xiàn)中,我們需要把查詢過(guò)程寫在Java 類中,這樣非常不便于后期維護(hù)。而使用Mybatis 則可以將查詢語(yǔ)句配置在配置文件中,只需要維護(hù)好映射關(guān)系即可。
Mybatis是一個(gè)開(kāi)源的輕量級(jí)半自動(dòng)化ORM框架,使得面向?qū)ο髴?yīng)用程序與關(guān)系數(shù)據(jù)庫(kù)的映射變得更加容易。熟悉Mybatis的都知道,其源碼里涉及到非常多的設(shè)計(jì)模式,比如
設(shè)計(jì)模式
Builder模式****:例如SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder、CacheBuilder;
工廠模式:例如SqlSessionFactory、ObjectFactory、MapperProxyFactory;
單例模式:例如ErrorContext和LogFactory;
代理模式:Mybatis實(shí)現(xiàn)的核心,比如MapperProxy、ConnectionLogger,用的jdk的動(dòng)態(tài)代理;還有executor.loader 包 使用了cglib或者javassist達(dá)到延遲加載的效果;
組合模式:例如SqlNode和各個(gè)子類ChooseSqlNode等;
模板方法模式:例如BaseExecutor和SimpleExecutor,還有BaseTypeHandler和所有的子類例如IntegerTypeHandler;
適配器模式:例如Log的Mybatis接口和它對(duì)jdbc、log4j等各種日志框架的適配實(shí)現(xiàn);
裝飾者模式:例如Cache包中的cache.decorators子包中等各個(gè)裝飾者的實(shí)現(xiàn);
迭代器模式:例如迭代器模式PropertyTokenizer;
關(guān)注公眾號(hào)“程序員白楠楠”獲取一份562頁(yè)的設(shè)計(jì)模式資料
如果之前只會(huì)使用或者沒(méi)有看過(guò)Mybatis源碼,那看到上面這些設(shè)計(jì)模式可能會(huì)有點(diǎn)懵逼。Mybatis用了這么多年了,只會(huì)用它來(lái)CRUD數(shù)據(jù)庫(kù)嗎?其底層的架構(gòu)設(shè)計(jì)與源碼分析,如何連接數(shù)據(jù)庫(kù)的?如何執(zhí)行的?一二級(jí)緩存的作用?sql如何解析的?源碼中設(shè)計(jì)到的設(shè)計(jì)模式......這些技術(shù)點(diǎn)都會(huì)嗎?
Mybatis源碼分析
今天,我們就來(lái)看看Mybatis源碼的閱讀,具體舉個(gè)例子來(lái)看看:
案例和疑問(wèn)
從我們最初的demo中開(kāi)始:
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
SqlSession sqlSession = null;
try {
inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectById", 1);
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
sqlSession.close();
}
}
關(guān)于獲取數(shù)據(jù)流inputStream,這個(gè)我們就不討論了,我們主要關(guān)注重點(diǎn)。
對(duì)于上面demo,我們可以分成五個(gè)步驟:
第一步,創(chuàng)建一個(gè)工廠類sqlSessionFactory。
配置文件的解析就是在這里完成的。包括mybatis-config.xml和我們的Mapper.xml映射器文件。這一步我們關(guān)心的內(nèi)容是:解析的時(shí)候做了什么?產(chǎn)生了什么對(duì)象,解析的結(jié)果放在哪里的。因?yàn)檫@將意味著,我們后面使用的時(shí)候去哪里獲取這項(xiàng)配置項(xiàng)內(nèi)容。
第二步,通過(guò)SqlSessionFactory創(chuàng)建一個(gè)SqlSession。
那么問(wèn)題來(lái)了,SqlSession中定義了各種增刪改查的API,是給客戶端調(diào)用,返回的是什么實(shí)現(xiàn)類?除了SqlSession以外,我們還創(chuàng)建了什么對(duì)象,創(chuàng)建了什么環(huán)境?
第三步,獲取到一個(gè)Mapper對(duì)象。
問(wèn)題來(lái)了UserMapper.java是一個(gè)接口,并沒(méi)有為它創(chuàng)建實(shí)現(xiàn)類,那又是怎么被實(shí)例化的呢?我們使用的這個(gè)Mapper對(duì)象到底是什么對(duì)象呢?為什么要從SqlSession里去獲取呢?為什么傳進(jìn)去一個(gè)接口,然后還要用一個(gè)接口去接收呢?
第四步,調(diào)用接口方法。
問(wèn)題是我們的接口沒(méi)有實(shí)現(xiàn)類,為什么就可以直接調(diào)用它的方法呢?那它調(diào)用的是誰(shuí)的方法呢?是如何把SQL給關(guān)聯(lián)起來(lái)的呢?是如何獲取到數(shù)據(jù)的呢?
第五步,關(guān)閉相關(guān)資源。
開(kāi)始源碼分析過(guò)程
由于涉及到內(nèi)容較多,下面就用幾張圖來(lái)展示整個(gè)流程。我們可以通過(guò)這幾張圖來(lái)快速翻閱Mybatis的源碼。
第一步
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
這一句代碼的整個(gè)流程如下:
根據(jù)inputStream,解析配置文件,創(chuàng)建出一個(gè)DefaultSqlSessionFactory默認(rèn)的SqlSessionFactory 實(shí)現(xiàn)類。構(gòu)建出一個(gè)工廠類,這個(gè)工廠類專門用來(lái)創(chuàng)建SqlSession對(duì)象的。
第二步
SqlSession sqlSession = sqlSessionFactory.openSession();
獲取SqlSession的整個(gè)流程如下:
第三步
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectById", 1);
第三步和第四步就是這行代碼畫的。
這一步是返回一個(gè)映射器代理類,映射器代理類專門用來(lái)給UserMapper接口和UserMapper.xml綁定的代理類。創(chuàng)建出來(lái)的代理類就可以實(shí)例化了,然后就可以調(diào)用UserMapper接口的方了。
第四步:調(diào)用代理對(duì)象執(zhí)行SQL的整個(gè)過(guò)程。
第五步,關(guān)閉資源。
希望大家按照這個(gè)流程,找點(diǎn)源碼看看。聽(tīng)別人的看別人永遠(yuǎn)是別人的。
動(dòng)起來(lái)吧!
個(gè)人建議
對(duì)于一般java程序員來(lái)說(shuō),閱讀源碼之前到底需要些什么技能呢?
個(gè)人建議,以下基礎(chǔ)知識(shí)必須會(huì)一些:
會(huì)設(shè)計(jì)模式:包括單例模式、工廠模式、代理模式、裝飾器模式、責(zé)任鏈模式、模板方法模式等。
會(huì)猜測(cè):大膽的猜測(cè),在看源碼的時(shí)候,多站在高層次想想,如果你是Mybatis的設(shè)計(jì)者,你會(huì)怎么設(shè)計(jì)?
總結(jié)
Mybatis應(yīng)該是國(guó)內(nèi)用得最多的「數(shù)據(jù)訪問(wèn)層」框架了,看了我司的好幾個(gè)系統(tǒng),基本都是用Mybatis。所以深入了解Mybatis的重要性不言而喻。
小編總結(jié)一份562頁(yè)的設(shè)計(jì)模式資料, 這份資料非常全面且詳細(xì),覆蓋了 設(shè)計(jì)模式 基礎(chǔ)學(xué)習(xí)的方方面面,非常適合初學(xué)者入門!
資料獲取方式:關(guān)注公眾號(hào)“程序員白楠楠”獲取上述資料!