<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
上文講的MyBatis部署執行且根據官網執行了一個demo:一步到位部署執行MyBatis3原始碼<保姆級>
再貼一個JDBC執行的測試方法,流程為:
@Test public void jdbcTest(){ String driver = "com.mysql.cj.jdbc.Driver"; String url = "jdbc:mysql://localhost:3306/news?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true"; String user = "root"; String pwd = "root123456"; Connection connection=null; ResultSet rs=null; PreparedStatement stmt=null; try { Class.forName(driver); //獲取資料庫連線 connection = DriverManager.getConnection(url,user,pwd); String sql = "select * from t_level where name=?"; //建立Statement物件(每一個Statement為一次資料庫執行請求) stmt=connection.prepareStatement(sql); //設定傳入引數 stmt.setString(1,"zhangsan"); //執行SQL語句 rs = stmt.executeQuery(sql); ResultSetMetaData metaData =rs.getMetaData(); //處理查詢結果-----此處未做操作 int columnCount= metaData.getColumnCount(); System.out.println(columnCount); } catch (Exception e) { e.printStackTrace(); }finally { try{ //關閉結果集 if(rs!=null){ rs.close(); rs=null; } //關閉執行 if(stmt!=null){ stmt.close(); stmt=null; } if(connection!=null){ connection.close(); connection=null; } }catch(SQLException e){ e.printStackTrace(); } } }
拿JDBC測試用例和上文mybatis的測試用例對比,可以發現哪些些共同點?
@Test public void test() throws IOException { InputStream input = Resources.getResourceAsStream("SqlSessionConfig.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(input); SqlSession sqlSession = sessionFactory.openSession(); LevelDao dao = sqlSession.getMapper(LevelDao.class); List<Level> all = dao.findAll(); }
首先他們都要有資料來源,這是毋庸置疑的。其次還要有執行sql語句,再有就是執行操作。
接下來進入到原始碼分析階段。
由於我們是根據官網 Building SqlSessionFactory from XML的方式來測試demo的,接下來我們的解析就按照XML檔案設定形式來講解。
資料來源4大元素包括:驅動、 url、 使用者名稱、 密碼。
在看程式碼之前,先看一下我們的組態檔結構。
mybatis是什麼時候獲取到資料來源的呢?要從測試方法生成SqlSessionFactory說起。
通過斷點進入到SqlSessionFactoryBuilder
的build
方法中,方法體就兩行關鍵程式碼,首先new了一個XML 設定生成器
,接著呼叫了其parse()生成一個Configuration
物件。
public SqlSessionFactory build(Reader reader, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { reader.close(); } catch (IOException e) { } } } public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }
parse方法執行了下面這條語句:
parseConfiguration(parser.evalNode("/configuration"));
parser.evalNode
會生成一個mybatis封裝的XNode
物件,copy後發現就是我們組態檔中<configuration>
標籤中的內容。
進入到parseConfiguration
方法中,可以看出好多方法的字串引數都和我們<configuration>
標籤中的一些標籤名稱相同。沒錯,每一步都是去掃描到對應引數的標籤內容從而進行一些設定處理。
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); } }
我們此處不研究其他處內容,直接看environmentsElement
方法的內容。root.evalNode("environments")
返回的XNode物件的value就是我們的environments
標籤內容。
進入到environmentsElement
方法中,會迴圈遍歷下一級的environment
,此處便是解析xml設定多資料來源的地方。
private void environmentsElement(XNode context) throws Exception { if (context != null) { if (environment == null) { environment = context.getStringAttribute("default"); } //xml設定多資料來源 for (XNode child : context.getChildren()) { String id = child.getStringAttribute("id"); if (isSpecifiedEnvironment(id)) { TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager")); //<dataSource></dataSource> DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource")); //獲得到資料庫源 DataSource dataSource = dsFactory.getDataSource(); Environment.Builder environmentBuilder = new Environment.Builder(id) .transactionFactory(txFactory) .dataSource(dataSource); configuration.setEnvironment(environmentBuilder.build()); } } } }
dataSourceElement
方法會拿到dataSource
標籤的內容生成一個DataSourceFactory
,並根據我們的設定給其屬性賦值。
通過getDataSource()
方法便可以拿到我們的資料來源。
最後呼叫configuration.setEnvironment
給到全域性設定中的。
執行流程圖如下:
到此這篇關於MyBatis3原始碼解析之如何獲取資料來源的文章就介紹到這了,更多相關MyBatis3獲取資料來源內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45