最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Mybatis是如何解析配置文件的

 更新時(shí)間:2020年12月16日 11:00:06   作者:諾淺  
這篇文章主要介紹了詳解Mybatis是如何解析配置文件的,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

緣起

經(jīng)過(guò)前面三章的入門(mén),我們大概了解了Mybatis的主線邏輯是什么樣子的,在本章中,我們將正式進(jìn)入Mybatis的源碼海洋。

Mybatis是如何解析xml的

構(gòu)建Configuration

在這里插入圖片描述

我們調(diào)用new SqlSessionFactoryBuilder().build()方法的最終目的就是構(gòu)建 Configuration對(duì)象,那么Configuration何許人也?Configuration對(duì)象是一個(gè)配置管家, Configuration對(duì)象之中維護(hù)著所有的配置信息。
Configuration的代碼片段如下

public class Configuration {
 //環(huán)境
 protected Environment environment;
 protected boolean safeRowBoundsEnabled;
 protected boolean safeResultHandlerEnabled = true;
 protected boolean mapUnderscoreToCamelCase;
 protected boolean aggressiveLazyLoading;
 protected boolean multipleResultSetsEnabled = true;
 protected boolean useGeneratedKeys;
 protected boolean useColumnLabel = true;
 protected boolean cacheEnabled = true;
 protected boolean callSettersOnNulls;
 protected boolean useActualParamName = true;
 protected boolean returnInstanceForEmptyRow;
 
 //日志信息的前綴
 protected String logPrefix;
 
 //日志接口
 protected Class<? extends Log> logImpl;
 
 //文件系統(tǒng)接口
 protected Class<? extends VFS> vfsImpl;
 
 //本地Session范圍
 protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
 
 //數(shù)據(jù)庫(kù)類型
 protected JdbcType jdbcTypeForNull = JdbcType.OTHER;
 
 //延遲加載的方法
 protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(
   Arrays.asList(new String[] { "equals", "clone", "hashCode", "toString" }));
 
 //默認(rèn)執(zhí)行語(yǔ)句超時(shí)
 protected Integer defaultStatementTimeout;
 
 //默認(rèn)的執(zhí)行器
 protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
 
 //數(shù)據(jù)庫(kù)ID
 protected String databaseId;
 
 //mapper注冊(cè)表
 protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
 
 //攔截器鏈
 protected final InterceptorChain interceptorChain = new InterceptorChain();
 
 //類型處理器
 protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
 
 //類型別名
 protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
 
 //語(yǔ)言驅(qū)動(dòng)
 protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry();

 //mapper_id 和 mapper文件的映射
 protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>(
   "Mapped Statements collection");
   
 //mapper_id和緩存的映射
 protected final Map<String, Cache> caches = new StrictMap<Cache>("Caches collection");
 
 //mapper_id和返回值的映射
 protected final Map<String, ResultMap> resultMaps = new StrictMap<ResultMap>("Result Maps collection");
 
 //mapper_id和參數(shù)的映射
 protected final Map<String, ParameterMap> parameterMaps = new StrictMap<ParameterMap>("Parameter Maps collection");
 
 //資源列表
 protected final Set<String> loadedResources = new HashSet<String>();
 
 未完.......
}

構(gòu)建MappedStatement

在Configuration中,有個(gè)mappedStatements的屬性,這是個(gè)MappedStatement對(duì)象Map的集合,其key是這個(gè)mapper的namespace+對(duì)應(yīng)節(jié)點(diǎn)的id,而value是一個(gè)MappedStatement對(duì)象。
在構(gòu)建Configuration的時(shí)候,會(huì)去解析我們的配置文件。
解析配置文件的關(guān)鍵代碼如下

private void parseConfiguration(XNode root) {
 try {
 //issue #117 read properties first
 propertiesElement(root.evalNode("properties"));
 Properties settings = settingsAsProperties(root.evalNode("settings"));
 loadCustomVfs(settings);
 loadCustomLogImpl(settings);
 typeAliasesElement(root.evalNode("typeAliases"));
 pluginElement(root.evalNode("plugins"));
 objectFactoryElement(root.evalNode("objectFactory"));
 objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
 reflectorFactoryElement(root.evalNode("reflectorFactory"));
 settingsElement(settings);
 // read it after objectFactory and objectWrapperFactory issue #631
 environmentsElement(root.evalNode("environments"));
 databaseIdProviderElement(root.evalNode("databaseIdProvider"));
 typeHandlerElement(root.evalNode("typeHandlers"));
 mapperElement(root.evalNode("mappers"));
 } catch (Exception e) {
 throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
 }
}

上訴代碼段倒數(shù)第三行mapperElement(root.evalNode("mappers"));就是解析mappers處就是把我們的mapper文件封裝成MappedStatement對(duì)象,然后保存到Configuration的mappedStatements屬性中,其中key是這個(gè)mapper的namespace+對(duì)應(yīng)節(jié)點(diǎn)的id,而value是一個(gè)MappedStatement對(duì)象。保存的地方關(guān)鍵代碼如下

configuration.addMappedStatement(statement);

addMappedStatement()方法代碼如下

protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>(
   "Mapped Statements collection");

public void addMappedStatement(MappedStatement ms) {
mappedStatements.put(ms.getId(), ms);
}

那么這個(gè)MappedStatement的又是何許人也?我們可以簡(jiǎn)單的把MapperStatement理解為對(duì)sql的一個(gè)封裝,在MappedStatement中保存著一個(gè)SqlSource對(duì)象,其中就存有SQL的信息。相關(guān)代碼如下

public final class MappedStatement {
	private SqlSource sqlSource;
}

SqlSource 代碼如下

public interface SqlSource {
 BoundSql getBoundSql(Object parameterObject);
}

BoundSql代碼如下

public class BoundSql {
 private final String sql;
 private final List<ParameterMapping> parameterMappings;
}

關(guān)于二級(jí)緩存
我們?cè)贑onfiguration中看到了一個(gè)caches屬性

protected final Map<String, Cache> caches = new StrictMap<>("Caches collection");

這個(gè)東西的作用是什么呢?其實(shí)是關(guān)于Mybatis的二級(jí)緩存的。在解析配置文件的過(guò)程中,如果用到了二級(jí)緩存,便會(huì)把這個(gè)ID和對(duì)象也保存到configuration的caches中,相關(guān)代碼如下

public void addCache(Cache cache) {
 caches.put(cache.getId(), cache);
}

構(gòu)建SqlSessionFactory

在Configuration對(duì)象構(gòu)建完畢之后,就該依賴Configuration對(duì)象去構(gòu)建SqlSessionFactory對(duì)象了,相關(guān)代碼如下

public SqlSessionFactory build(Configuration config) {
 return new DefaultSqlSessionFactory(config);
}

我們暫且把SqlSessionFactory稱為SqlSession工廠吧,SqlSessionFactory中有兩個(gè)方法,openSession()和getConfiguration()
SqlSessionFactory代碼如下

public interface SqlSessionFactory {
 SqlSession openSession();
 //其余openSession重載方法略…
 Configuration getConfiguration();
}

構(gòu)建SqlSession

openSession()方法會(huì)返回一個(gè)SqlSession對(duì)象,SqlSession又是何許人也?SqlSession可以理解為程序與數(shù)據(jù)庫(kù)打交道的一個(gè)工具,通過(guò)它,程序可以往數(shù)據(jù)庫(kù)發(fā)送SQL執(zhí)行。
SqlSession代碼如下

public interface SqlSession extends Closeable {
 <T> T selectOne(String statement);
 <T> T selectOne(String statement, Object parameter);
 <E> List<E> selectList(String statement);
 <E> List<E> selectList(String statement, Object parameter);
 //其余增刪查改方法略…
}

總結(jié)

想必你已經(jīng)明白了,Mybatis解析xml最主要的目的其實(shí)是構(gòu)建Configuration對(duì)象,這個(gè)對(duì)象中可以說(shuō)包含著Mybatis的所有配置信息。其中有一個(gè)mappedStatements屬性,這是一個(gè)Map,其中key是這個(gè)mapper的namespace+對(duì)應(yīng)節(jié)點(diǎn)的id,而value是一個(gè)MappedStatement對(duì)象,而MappedStatement中保存著一個(gè)SqlSource對(duì)象,這個(gè)對(duì)象中保存著我們要執(zhí)行的SQL語(yǔ)句。

那么在下一章,我們將一起探究Mybatis是如何執(zhí)行我們的SQL語(yǔ)句的。

到此這篇關(guān)于詳解Mybatis是如何解析配置文件的的文章就介紹到這了,更多相關(guān)Mybatis 解析配置文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot事務(wù)失效的原因及解決辦法詳解

    Springboot事務(wù)失效的原因及解決辦法詳解

    這篇文章主要介紹了Springboot事務(wù)失效的原因及解決辦法詳解,spring中的事務(wù)是依賴AOP的,AOP是通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)的,只有通過(guò)代理類訪問(wèn)的方法才能被攔截,而addMultiFile直接內(nèi)部調(diào)用了addFile方法,所以addFile中的事務(wù)就不會(huì)生效
    2023-10-10
  • 淺析如何高效格式化輸出JSON字符串

    淺析如何高效格式化輸出JSON字符串

    JSON(JavaScript?Object?Notation)作為一種輕量級(jí)的數(shù)據(jù)交換格式,已經(jīng)成為了各種編程語(yǔ)言間傳遞數(shù)據(jù)的標(biāo)準(zhǔn),下面我們就來(lái)聊聊如何高效格式化輸出JSON字符串吧
    2025-01-01
  • SpringBoot導(dǎo)入Druid運(yùn)行失敗問(wèn)題

    SpringBoot導(dǎo)入Druid運(yùn)行失敗問(wèn)題

    這篇文章主要介紹了SpringBoot導(dǎo)入Druid運(yùn)行失敗,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • java程序代碼與文本對(duì)比實(shí)用工具簡(jiǎn)介

    java程序代碼與文本對(duì)比實(shí)用工具簡(jiǎn)介

    可以對(duì)兩段文本進(jìn)行對(duì)比,檢測(cè)/比較兩個(gè)文本有什么不同的差異,以便修改,常用于程序代碼,就是不需要人工查看,尤其是大文件,有幾百上千行的代碼,這時(shí)候就建議使用比較工具了,不用浪費(fèi)過(guò)多時(shí)間去尋找
    2021-09-09
  • List集合多線程并發(fā)條件下不安全如何解決

    List集合多線程并發(fā)條件下不安全如何解決

    List是我們常用的集合,但是在多線程并發(fā)的條件下,會(huì)出現(xiàn)安全問(wèn)題嗎?下面我們就來(lái)測(cè)試一下,如果出現(xiàn)安全問(wèn)題,該如何解決,感興趣的可以了解一下
    2021-12-12
  • springboot應(yīng)用服務(wù)啟動(dòng)事件的監(jiān)聽(tīng)實(shí)現(xiàn)

    springboot應(yīng)用服務(wù)啟動(dòng)事件的監(jiān)聽(tīng)實(shí)現(xiàn)

    本文主要介紹了springboot應(yīng)用服務(wù)啟動(dòng)事件的監(jiān)聽(tīng)實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • java使用WatchService監(jiān)控文件夾示例

    java使用WatchService監(jiān)控文件夾示例

    本篇文章主要介紹了java使用WatchService監(jiān)控文件夾示例的資料,這里整理了詳細(xì)的代碼,有需要的小伙伴可以參考下。
    2017-02-02
  • Spring Boot利用Thymeleaf發(fā)送Email的方法教程

    Spring Boot利用Thymeleaf發(fā)送Email的方法教程

    spring Boot默認(rèn)就是使用thymeleaf模板引擎的,下面這篇文章主要給大家介紹了關(guān)于在Spring Boot中利用Thymeleaf發(fā)送Email的方法教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-08-08
  • dom4j操作xml的demo(分享)

    dom4j操作xml的demo(分享)

    下面小編就為大家?guī)?lái)一篇dom4j操作xml的demo(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • 帶你全面認(rèn)識(shí)Java中的異常處理

    帶你全面認(rèn)識(shí)Java中的異常處理

    在你所寫(xiě)過(guò)的代碼中,你已經(jīng)接觸過(guò)一些異常了,我們可以通過(guò)一些簡(jiǎn)單的代碼讓我們理解一些簡(jiǎn)單的異常,下面這篇文章主要給大家介紹了關(guān)于Java中異常處理的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12

最新評(píng)論

长宁县| 盐津县| 石河子市| 舒城县| 南平市| 太仓市| 逊克县| 望江县| 治县。| 濮阳县| 礼泉县| 贵南县| 平邑县| 庄浪县| 昂仁县| 铅山县| 绵阳市| 义马市| 台安县| 阿鲁科尔沁旗| 长顺县| 汤原县| 密山市| 永仁县| 哈巴河县| 迭部县| 西峡县| 安阳市| 米泉市| 定日县| 通化县| 光山县| 屏东市| 新津县| 昌都县| 永寿县| 准格尔旗| 太白县| 甘洛县| 莒南县| 京山县|