mybatis實現原理深度理解

先放一張圖,讓大家簡單認識一下:

1、解析xml的時候

首先,Mybatis在初始化SqlSessionFactoryBean的時候,找到mapperLocations路徑去解析裏面所有的XML文件

2、創建sqlsource

Mybatis會把每個SQL標籤封裝成SqlSource對象。然後根據SQL語句的不同,又分爲動態SQL和靜態SQL。其中,靜態SQL包含一段String類型的sql語句;而動態SQL則是由一個個SqlNode組成

3、創建mappedStatement

XML文件中的每一個SQL標籤就對應一個MappedStatement對象,這裏面有兩個屬性很重要。
id
全限定類名+方法名組成的ID。
sqlSource
當前SQL標籤對應的SqlSource對象。
創建完MappedStatement對象,將它緩存到Configuration#mappedStatements中。
Configuration對象,我們知道它就是Mybatis中的大管家,基本所有的配置信息都維護在這裏。把所有的XML都
解析完成之後,Configuration就包含了所有的SQL信息。
到目前爲止,XML就解析完成了。看到上面的圖示,聰明如你,也許就大概知道了。當我們執行Mybatis方法的時
候,就通過全限定類名+方法名找到MappedStatement對象,然後解析裏面的SQL內容,執行即可。

4、dao接口代理

你的項目是基於SpringBoot的,那麼肯定也見過這種:
@MapperScan("com.xxx.dao")
它們的作用是一樣的。將包路徑下的所有類註冊到Spring Bean中,並且將它們的beanClass設置爲
MapperFactoryBean。有意思的是,MapperFactoryBean實現了FactoryBean接口,俗稱工廠Bean。那麼,當我
們通過@Autowired注入這個Dao接口的時候,返回的對象就是MapperFactoryBean這個工廠Bean中的
getObject()方法對象。
那麼,這個方法幹了些什麼呢?
簡單來說,它就是通過JDK動態代理,返回了一個Dao接口的代理對象,這個代理對象的處理器是MapperProxy對
象。所有,我們通過@Autowired注入Dao接口的時候,注入的就是這個代理對象,我們調用到Dao接口的方法時,
則會調用到MapperProxy對象的invoke方法。

5、執行

當我們調用Dao接口方法的時候,實際調用到代理對象的invoke方法。
在這裏,實際上調用的就是SqlSession裏面的東西了
public class DefaultSqlSession implements SqlSession {
   public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
        try {
            MappedStatement ms = configuration.getMappedStatement(statement); 
            return executor.query(ms, 
                wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); 
        }
    }
}

它就是通過statement全限定類型+方法名拿到MappedStatement 對象,然後通過執行器Executor去執行具體SQL並返回

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章