您好,登錄后才能下訂單哦!
Mybatis如何創建SqlSession以及Excutor的使用,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
今天我們分析下Mybatis如何創建SqlSession( sessionFactory.openSession())和Excutor到底做了什么事情
public static void main(String[] args) throws Exception {
SqlSessionFactory sessionFactory = null;
String resource = "configuration.xml";
sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(resource));
SqlSession sqlSession = sessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
System.out.println(userMapper.findUserById(1));
}
通過openSession()最終調用的是 openSessionFromDataSource,源碼如下:
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
說明:ExecutorType(執行器類型)類型有 SIMPLE(默認),REUSE,BATCH,
TransactionIsolationLevel 隔離級別5種
NONE(Connection.TRANSACTION_NONE), READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED), READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED), REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ),
SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE);
通過源碼看出首先是從configuration獲取environment,接著創建Transaction,
最后通過 configuration.newExecutor創建Executor。
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
//根據executorType創建不同的Executor對象
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);
}
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
根據executorType創建對應的Executor,從源碼可以看出他有BatchExecutor、ReuseExecutor、CachingExecutor、SimpleExecutor
那么Executor是做什么的呢?
Executor是接口,是對于Statement的封裝,我們看下Executor,他是真正執行sql的地方。
public interface Executor {
ResultHandler NO_RESULT_HANDLER = null;
int update(MappedStatement ms, Object parameter) throws SQLException;
List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
Cursor queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;
List flushStatements() throws SQLException;
void commit(boolean required) throws SQLException;
void rollback(boolean required) throws SQLException;
CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);
boolean isCached(MappedStatement ms, CacheKey key);
void clearLocalCache();
void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class targetType);
Transaction getTransaction();
void close(boolean forceRollback);
boolean isClosed();
void setExecutorWrapper(Executor executor);
}
上面源碼我可以看到Executor接口定義了update 、query、commit、rollback等方法,他的實現類如下圖
我們拿其中的SimpleExecutor類里面的doQuery方法看下源碼
@Override
public List doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
Statement stmt = null;
try {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
//StatementHandler封裝了Statement, 讓 StatementHandler 去處理
stmt = prepareStatement(handler, ms.getStatementLog());
return handler.query(stmt, resultHandler);
} finally {
closeStatement(stmt);
}
}
我們看看StatementHandler 的一個實現類 PreparedStatementHandler(這也是我們最常用的,封裝的是PreparedStatement), 看看它使怎么去處理的:
@Override
public List query(Statement statement, ResultHandler resultHandler) throws SQLException {
String sql = boundSql.getSql();
//這個和jdbc一樣執行sql
statement.execute(sql);
//結果交給了ResultSetHandler 去處理
return resultSetHandler.handleResultSets(statement);
}
我們繼續回到openSessionFromDataSource上面來,通過上面的executor的創建最終是創建 new DefaultSqlSession(configuration, executor, autoCommit)。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。