成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Mybatis是如何解析配置文件的?看完終于明白了

開發(fā) 前端
在以前文章中,我們把Mybatis源碼閱讀的整個流程梳理了一遍。今天,我們來詳細(xì)聊聊,Mybatis是如何解析配置文件的。

[[357645]]

在以前文章中,我們把Mybatis源碼閱讀的整個流程梳理了一遍。今天,我們來詳細(xì)聊聊,Mybatis是如何解析配置文件的。

這是今天分析的流程圖:

 

還是從案例開始。

demo案例

  1. public static void main(String[] args) { 
  2.         String resource = "mybatis-config.xml"
  3.         InputStream inputStream = null
  4.         SqlSession sqlSession = null
  5.         try { 
  6.             inputStream = Resources.getResourceAsStream(resource); 
  7.             SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 
  8.             sqlSession = sqlSessionFactory.openSession(); 
  9.  
  10.             UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 
  11.             System.out.println(userMapper.selectById(1)); 
  12.  
  13.         } catch (Exception e) { 
  14.             e.printStackTrace(); 
  15.         } finally { 
  16.             try { 
  17.                 inputStream.close(); 
  18.             } catch (IOException e) { 
  19.                 e.printStackTrace(); 
  20.             } 
  21.             sqlSession.close(); 
  22.         } 
  23.     } 

見證奇跡

從SqlSessionFactoryBuilder開始。

SqlSessionFactoryBuilder類

  1. org.apache.ibatis.session.SqlSessionFactoryBuilder 

該類里全是build方法各種重載。

  1. //這個方法啥也沒干   
  2. public SqlSessionFactory build(InputStream inputStream) { 
  3.     return build(inputStream, nullnull); 
  4.  } 

最終來到另外一個build方法里:

  1. public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { 
  2.    try { 
  3.      //創(chuàng)建一個XMLConfigBuilder對象   
  4.      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); 
  5.      return build(parser.parse()); 
  6.    } catch (Exception e) { 
  7.      throw ExceptionFactory.wrapException("Error building SqlSession.", e); 
  8.    } finally { 
  9.      ErrorContext.instance().reset(); 
  10.      try { 
  11.        inputStream.close(); 
  12.      } catch (IOException e) { 
  13.        // Intentionally ignore. Prefer previous error. 
  14.      } 
  15.    } 
  16.  } 

XMLConfigBuilder類

該類的構(gòu)造方法重載:

 

首先進(jìn)入:

  1. public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) { 
  2.     this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment,      
  3.          props); 
  4. private XMLConfigBuilder(XPathParser parser, String environment, Properties props) { 
  5.     super(new Configuration()); 
  6.     ErrorContext.instance().resource("SQL Mapper Configuration"); 
  7.     this.configuration.setVariables(props); 
  8.     this.parsed = false
  9.     this.environment = environment; 
  10.     this.parser = parser; 

build(parser.parse());中的parser.parse();

mybatis-config.xml在哪里解析的呢?

請看下面這個方法:

  1. //該方法返回一個Configuration對象 
  2. public Configuration parse() { 
  3.   if (parsed) { 
  4.     throw new BuilderException("Each XMLConfigBuilder can only be used once."); 
  5.   } 
  6.   parsed = true
  7.   //關(guān)鍵點(diǎn) 
  8.   parseConfiguration(parser.evalNode("/configuration")); 
  9.   return configuration; 

parseConfiguration(parser.evalNode("/configuration"));

終于看到開始解析配置文件了:

 

進(jìn)入方法parseConfiguration。

  1. private void parseConfiguration(XNode root) { 
  2.   try { 
  3.     //issue #117 read properties first 
  4.     propertiesElement(root.evalNode("properties")); 
  5.     Properties settings = settingsAsProperties(root.evalNode("settings")); 
  6.     loadCustomVfs(settings); 
  7.     loadCustomLogImpl(settings); 
  8.     typeAliasesElement(root.evalNode("typeAliases")); 
  9.     pluginElement(root.evalNode("plugins")); 
  10.     objectFactoryElement(root.evalNode("objectFactory")); 
  11.     objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); 
  12.     reflectorFactoryElement(root.evalNode("reflectorFactory")); 
  13.     settingsElement(settings); 
  14.     // read it after objectFactory and objectWrapperFactory issue #631 
  15.     environmentsElement(root.evalNode("environments")); 
  16.     databaseIdProviderElement(root.evalNode("databaseIdProvider")); 
  17.     typeHandlerElement(root.evalNode("typeHandlers")); 
  18.     mapperElement(root.evalNode("mappers")); 
  19.   } catch (Exception e) { 
  20.     throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); 
  21.   } 

這里就是把mybatis-config.xml內(nèi)容解析,然后設(shè)置到Configuration對象中。

那么我們定義的Mapper.xml是在哪里解析的呢?

我們的Mapper.xml在mybatis-config.xml中的配置是這樣的:

 

使用方式有以下四種:

  1. //1使用類路徑 
  2. <mappers> 
  3.     <mapper resource="org/mybatis/builder/AuthorMapper.xml"/> 
  4.       <mapper resource="org/mybatis/builder/BlogMapper.xml"/> 
  5.    <mapper resource="org/mybatis/builder/PostMapper.xml"/> 
  6. </mappers> 
  7. //2使用絕對url路徑 
  8. <mappers> 
  9.    <mapper url="file:///var/mappers/AuthorMapper.xml"/> 
  10.    <mapper url="file:///var/mappers/BlogMapper.xml"/> 
  11.    <mapper url="file:///var/mappers/PostMapper.xml"/> 
  12. </mappers> 
  13. //3使用java類名 
  14. <mappers> 
  15.    <mapper class="org.mybatis.builder.AuthorMapper"/> 
  16.    <mapper class="org.mybatis.builder.BlogMapper"/> 
  17.    <mapper class="org.mybatis.builder.PostMapper"/> 
  18. </mappers> 
  19.  
  20. //4自動掃描包下所有映射器 
  21. <mappers> 
  22.    <package name="org.mybatis.builder"/> 
  23. </mappers> 

繼續(xù)源碼分析,我們在上面mybatis-config.xml解析中可以看到:

 

我們不妨進(jìn)入這個方法看看:

  1. private void mapperElement(XNode parent) throws Exception { 
  2.    if (parent != null) { 
  3.      for (XNode child : parent.getChildren()) { 
  4.        //自動掃描包下所有映射器 
  5.        if ("package".equals(child.getName())) { 
  6.          String mapperPackage = child.getStringAttribute("name"); 
  7.          //放   
  8.          configuration.addMappers(mapperPackage); 
  9.        } else { 
  10.          String resource = child.getStringAttribute("resource"); 
  11.          String url = child.getStringAttribute("url"); 
  12.          String mapperClass = child.getStringAttribute("class"); 
  13.          //使用java類名 
  14.          if (resource != null && url == null && mapperClass == null) { 
  15.            ErrorContext.instance().resource(resource); 
  16.             //根據(jù)文件存放目錄,讀取XxxMapper.xml 
  17.            InputStream inputStream = Resources.getResourceAsStream(resource); 
  18.             //映射器比較復(fù)雜,調(diào)用XMLMapperBuilder 
  19.            //注意在for循環(huán)里每個mapper都重新new一個XMLMapperBuilder,來解析 
  20.            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments()); 
  21.            mapperParser.parse(); 
  22.          //使用絕對url路徑 
  23.          } else if (resource == null && url != null && mapperClass == null) { 
  24.            ErrorContext.instance().resource(url); 
  25.            InputStream inputStream = Resources.getUrlAsStream(url); 
  26.            //映射器比較復(fù)雜,調(diào)用XMLMapperBuilder 
  27.            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments()); 
  28.            mapperParser.parse(); 
  29.          //使用類路徑     
  30.          } else if (resource == null && url == null && mapperClass != null) { 
  31.            Class<?> mapperInterface = Resources.classForName(mapperClass); 
  32.            //直接把這個映射加入配置 
  33.            configuration.addMapper(mapperInterface); 
  34.          } else { 
  35.            throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one."); 
  36.          } 
  37.        } 
  38.      } 
  39.    } 
  40.  } 

這里剛剛和我們的上面說的使用的方式完全是一模一樣的。

到這里,配置文件mybatis-config.xml和我們定義映射文件XxxMapper.xml就全部解析完成。

回到SqlSessionFactoryBuilder類

前面講到了XMLConfigBuilder中的parse方法,并返回了一個Configuration對象。

build(parser.parse());

這個build方法就是傳入一個Configuration對象,然后構(gòu)建一個DefaultSqlSession對象。

  1. public SqlSessionFactory build(Configuration config) { 
  2.   return new DefaultSqlSessionFactory(config); 

繼續(xù)回到我們的demo代碼中這一行代碼里:

  1. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 

這一行代碼就相當(dāng)于:

  1. SqlSessionFactory sqlSessionFactory = new new DefaultSqlSessionFactory(); 

 

到這里,我們的整個流程就搞定了。

本文轉(zhuǎn)載自微信公眾號「 Java后端技術(shù)全棧  」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系 Java后端技術(shù)全棧  公眾號。

 

責(zé)任編輯:武曉燕 來源: Java后端技術(shù)全棧
相關(guān)推薦

2021-07-08 21:19:04

BashLinux

2021-11-09 06:49:20

WiFi 6WiFi 5通信網(wǎng)絡(luò)

2021-06-28 21:04:09

顯示器花屏電腦

2020-01-06 08:40:11

阿里場景服務(wù)

2021-07-26 05:00:16

算法DfsBfs

2022-12-31 08:17:02

2022-02-25 07:07:04

擴(kuò)展塢電腦筆記本

2021-06-04 07:13:43

Logger TRACEDEBUG

2022-08-08 20:23:14

一網(wǎng)統(tǒng)管企業(yè)協(xié)商

2021-09-26 15:58:05

MySQL SQL 語句數(shù)據(jù)庫

2022-05-01 22:09:27

數(shù)據(jù)模型大數(shù)據(jù)

2022-03-27 20:32:28

Knative容器事件模型

2021-10-09 00:02:04

DevOps敏捷開發(fā)

2021-06-13 12:03:46

SaaS軟件即服務(wù)

2018-03-09 10:02:23

iPhone X下巴蘋果

2010-02-03 09:19:31

Python模塊

2021-10-17 20:38:30

微服務(wù)內(nèi)存組件

2021-03-25 11:24:25

爬蟲技術(shù)開發(fā)

2020-11-03 07:04:39

云計算公有云私有云

2022-04-27 18:25:02

數(shù)據(jù)采集維度
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美亚洲国产一区 | 久久综合久 | 国产精品一二三区 | 欧美激情一区二区 | 羞羞视频免费在线 | 在线成人免费视频 | 黑人巨大精品欧美一区二区免费 | 国产色婷婷精品综合在线手机播放 | 国产精品毛片无码 | 成人毛片网站 | 一道本不卡视频 | 欧美一二三四成人免费视频 | 国产视频不卡一区 | 在线视频国产一区 | 免费a v网站| 99久久久久久 | 日本不卡免费新一二三区 | 国产在线看片 | 国产午夜精品一区二区三区在线观看 | 欧美综合一区二区 | 国产亚洲精品区 | 国产中文 | 亚洲国产激情 | 成年人的视频免费观看 | 亚洲成人综合在线 | 国产成人精品久久二区二区91 | 日韩不卡一二区 | 国产不卡一区 | 伊人狼人影院 | 成人福利网 | 国产一区二区三区在线视频 | 国产美女一区 | 99精品久久久国产一区二区三 | 一区二区三区在线免费观看 | 欧美日韩国产中文字幕 | 亚洲色图网址 | 日本人做爰大片免费观看一老师 | 日韩一级免费大片 | 91视频88av | 在线视频91| 日韩av成人 |