那里可以做旅游網(wǎng)站的嗎我們公司在做網(wǎng)站推廣
前言:
前文我們從源碼層面梳理了 SqlSessionFactory 的創(chuàng)建過(guò)程,本篇我們繼續(xù)分析一下 SqlSession 的獲取過(guò)程。
初識(shí) MyBatis 【MyBatis 核心概念】
案例代碼:
public class MyBatisTest {@Testpublic void test() throws IOException {//讀取配置文件InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//創(chuàng)建 SqlSessionFactoryBuilder 對(duì)象SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//通過(guò) SqlSessionBuilder 對(duì)象 解析 mybatis-config.xml 文件 構(gòu)建一個(gè)SqlSessionFactory SqlSessionFactory sqlSessionFactory = builder.build(is);//通過(guò)SqlSessionFactory構(gòu)建一個(gè)SqlSessionSqlSession session = sqlSessionFactory.openSession();//通過(guò)SqlSession 獲取 Mapper 實(shí)例UserMapper userMapper = session.getMapper(UserMapper.class);//獲取數(shù)據(jù)List<User> users = userMapper.findAll();//打印輸出for (User user : users) {System.out.println(user);}//關(guān)閉資源session.close();is.close();}
}
本篇我們將主要對(duì) sqlSessionFactory.openSession() 這句代碼進(jìn)行分析。
獲取 SqlSession 源碼分析
DefaultSqlSessionFactory#openSession 方法源碼分析
DefaultSqlSessionFactory#openSession 方法只是調(diào)用了 DefaultSqlSessionFactory#openSessionFromDataSource 方法,并傳入了默認(rèn)的執(zhí)行器類(lèi)型、隔離級(jí)別、是否自動(dòng)提交參數(shù)。
//org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()
public SqlSession openSession() {//使用默認(rèn)的執(zhí)行器類(lèi)型(默認(rèn)是SIMPLE) 默認(rèn)隔離級(jí)別 非自動(dòng)提交 委托給 openSessionFromDataSource 方法return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
}
執(zhí)行器類(lèi)型
- SIMPLE:簡(jiǎn)單執(zhí)行器 SimpleExecutor,每執(zhí)行一條 SQL,都會(huì)打開(kāi)一個(gè) Statement,執(zhí)行完成后會(huì)關(guān)閉。
- REUSE:重用執(zhí)行器 ReuseExecutor,其內(nèi)部會(huì)緩存一個(gè) Map<String, Statement> ,每次編譯完成的 Statement 都會(huì)進(jìn)行緩存,不會(huì)關(guān)閉,可以重復(fù)使用。
- BATCH:批量執(zhí)行器,基于 JDBC 的 addBatch、executeBatch 功能,只能作用于 insert、update、delete 語(yǔ)句。
- CachingExecutor:緩存執(zhí)行器,使用了裝飾器模式,在開(kāi)啟緩存的時(shí)候,會(huì)在上面三種執(zhí)行器上包裝一層 CachingExecutor。
package org.apache.ibatis.session;public enum ExecutorType {SIMPLE,REUSE,BATCH;private ExecutorType() {}
}
DefaultSqlSessionFactory#openSessionFromDataSource 方法源碼分析
DefaultSqlSessionFactory#openSessionFromDataSource 方法邏輯很簡(jiǎn)單,先獲取創(chuàng)建 SqlSession 的必要參數(shù),然后調(diào)用 DefaultSqlSession 的構(gòu)造方法創(chuàng)建了 SqlSession 。
//org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {//事務(wù)Transaction tx = null;//SqlSessionDefaultSqlSession var8;try {//獲取環(huán)境Environment environment = this.configuration.getEnvironment();//獲取事務(wù)工廠TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);//獲取一個(gè)事務(wù)tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);//根據(jù) 事務(wù) 和 執(zhí)行器類(lèi)型創(chuàng)建一個(gè)執(zhí)行器Executor executor = this.configuration.newExecutor(tx, execType);//根據(jù)配置 執(zhí)行器 事務(wù)提交方式創(chuàng)建一個(gè)默認(rèn)的 SqlSessionvar8 = new DefaultSqlSession(this.configuration, executor, autoCommit);} catch (Exception var12) {this.closeTransaction(tx);throw ExceptionFactory.wrapException("Error opening session. Cause: " + var12, var12);} finally {ErrorContext.instance().reset();}return var8;
}//org.apache.ibatis.session.defaults.DefaultSqlSession#DefaultSqlSession(org.apache.ibatis.session.Configuration, org.apache.ibatis.executor.Executor, boolean)
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {this.configuration = configuration;this.executor = executor;this.dirty = false;this.autoCommit = autoCommit;
}
Configuration#newExecutor 方法源碼分析
Configuration#newExecutor 主要是對(duì)執(zhí)行器類(lèi)型進(jìn)行判斷,然后生成執(zhí)行器,并通過(guò)動(dòng)態(tài)代理得到代理對(duì)象,并將執(zhí)行器加入攔截器鏈。
//org.apache.ibatis.session.Configuration#newExecutor
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {executorType = executorType == null ? this.defaultExecutorType : executorType;executorType = executorType == null ? ExecutorType.SIMPLE : executorType;Object executor;//執(zhí)行器類(lèi)型判斷if (ExecutorType.BATCH == executorType) {executor = new BatchExecutor(this, transaction);} else if (ExecutorType.REUSE == executorType) {executor = new ReuseExecutor(this, transaction);} else {executor = new SimpleExecutor(this, transaction);}//是否開(kāi)啟緩存if (this.cacheEnabled) {//開(kāi)啟緩存 創(chuàng)建緩存執(zhí)行器executor = new CachingExecutor((Executor)executor);}//責(zé)任鏈模式 將執(zhí)行器加入攔截器鏈 使用JDK動(dòng)態(tài)代理增強(qiáng)所有的攔截器 Executor executor = (Executor)this.interceptorChain.pluginAll(executor);return executor;
}
獲取 SqlSession 的源碼很簡(jiǎn)單,希望可以幫助到有需要的小伙伴。
歡迎提出建議及對(duì)錯(cuò)誤的地方指出糾正。