查看“入门:入门程序代码追踪”的源代码
←
入门:入门程序代码追踪
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:Mybatis]] 【2020/10/08 01:28:55】 == 入口代码 == <syntaxhighlight lang="java" line highlight="14,22,25"> public class Mybatis_first { //会话工厂 private SqlSessionFactory sqlSessionFactory; @Before public void createSqlSessionFactory() throws IOException { // mybatis配置文件 String resource = "SqlMapConfig.xml"; // 得到配置文件流 InputStream inputStream = Resources.getResourceAsStream(resource); // 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } public void testFindUserById() { // 数据库会话实例 SqlSession sqlSession = null; try { // 创建数据库会话实例sqlSession sqlSession = sqlSessionFactory.openSession(); // selectOne查询出一条记录 User user = sqlSession.selectOne("test.findUserById", 1); </syntaxhighlight> == sqlSessionFactory代码 == 由入口:<syntaxhighlight lang="java" inline>sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);</syntaxhighlight>: <syntaxhighlight lang="java" line highlight="7,14,29"> package org.apache.ibatis.session; public class SqlSessionFactoryBuilder { ... public SqlSessionFactory build(InputStream inputStream) { return build(inputStream, null, null); } ... public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { inputStream.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } ... public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); } </syntaxhighlight> 得到sqlSessionFactory为'''DefaultSqlSessionFactory'''; * SqlSessionFactoryBuilder().build返回值均为DefaultSqlSessionFactory类型 == sqlSession代码 == 由入口:<syntaxhighlight lang="java" inline>sqlSession = sqlSessionFactory.openSession();</syntaxhighlight>:(由sqlSessionFactory可知,即“DefaultSqlSessionFactory.openSession()”) <syntaxhighlight lang="java" line highlight="12,19-23,34-37"> package org.apache.ibatis.session.defaults; public class DefaultSqlSessionFactory implements SqlSessionFactory { private final Configuration configuration; public DefaultSqlSessionFactory(Configuration configuration) { this.configuration = configuration; } public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); } ... 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(); } } ... private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) { if (environment == null || environment.getTransactionFactory() == null) { return new ManagedTransactionFactory(); } return environment.getTransactionFactory(); } </syntaxhighlight> 得到sqlSession为'''DefaultSqlSession'''; * DefaultSqlSessionFactory.openSession返回值均为DefaultSqlSession类型 * 如果SqlMapConfig.xml中没有Transaction,则返回默认的'''ManagedTransactionFactory''' * tx(Transaction)作为参数,用于构造Executor * 其中Environment、TransactionFactory、Executor均被final修饰 === Executor === 由sqlSession中<syntaxhighlight lang="java" inline>configuration.getDefaultExecutorType()</syntaxhighlight>、<syntaxhighlight lang="java" inline>final Executor executor = configuration.newExecutor(tx, execType);</syntaxhighlight>有: <syntaxhighlight lang="java" line highlight="5,9,21"> package org.apache.ibatis.session; public class Configuration { ... protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE; ... public ExecutorType getDefaultExecutorType() { return defaultExecutorType; } ... public Executor newExecutor(Transaction transaction, ExecutorType executorType) { executorType = executorType == null ? defaultExecutorType : executorType; executorType = executorType == null ? ExecutorType.SIMPLE : executorType; Executor 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; } </syntaxhighlight> 得到executor = new '''SimpleExecutor''',其源码如下: : <syntaxhighlight lang="java" line> package org.apache.ibatis.executor; ... public class SimpleExecutor extends BaseExecutor { public SimpleExecutor(Configuration configuration, Transaction transaction) { super(configuration, transaction); } public int doUpdate(MappedStatement ms, Object parameter) throws SQLException { Statement stmt = null; try { Configuration configuration = ms.getConfiguration(); StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null); stmt = prepareStatement(handler, ms.getStatementLog()); return handler.update(stmt); } finally { closeStatement(stmt); } } public <E> List<E> 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); stmt = prepareStatement(handler, ms.getStatementLog()); return handler.<E>query(stmt, resultHandler); } finally { closeStatement(stmt); } } public List<BatchResult> doFlushStatements(boolean isRollback) throws SQLException { return Collections.emptyList(); } private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException { Statement stmt; Connection connection = getConnection(statementLog); stmt = handler.prepare(connection); handler.parameterize(stmt); return stmt; } } </syntaxhighlight> === Transaction === 由sqlSession中<syntaxhighlight lang="java" inline>final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);</syntaxhighlight>、<syntaxhighlight lang="java" inline>return new ManagedTransactionFactory();</syntaxhighlight>有:<br/> <syntaxhighlight lang="java" inline>tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);</syntaxhighlight>即“ManagedTransactionFactory.newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit)”: <syntaxhighlight lang="java" line highlight="10"> package org.apache.ibatis.transaction.managed; public class ManagedTransactionFactory implements TransactionFactory { ... public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) { // Silently ignores autocommit and isolation level, as managed transactions are entirely // controlled by an external manager. It's silently ignored so that // code remains portable between managed and unmanaged configurations. return new ManagedTransaction(ds, level, closeConnection); } } </syntaxhighlight> 得到Transaction tx = new '''ManagedTransaction''',其源码如下: : <syntaxhighlight lang="java" line> package org.apache.ibatis.transaction.managed; ... public class ManagedTransaction implements Transaction { private static final Log log = LogFactory.getLog(ManagedTransaction.class); private DataSource dataSource; private TransactionIsolationLevel level; private Connection connection; private boolean closeConnection; public ManagedTransaction(Connection connection, boolean closeConnection) { this.connection = connection; this.closeConnection = closeConnection; } public ManagedTransaction(DataSource ds, TransactionIsolationLevel level, boolean closeConnection) { this.dataSource = ds; this.level = level; this.closeConnection = closeConnection; } public Connection getConnection() throws SQLException { if (this.connection == null) { openConnection(); } return this.connection; } public void commit() throws SQLException { // Does nothing } public void rollback() throws SQLException { // Does nothing } public void close() throws SQLException { if (this.closeConnection && this.connection != null) { if (log.isDebugEnabled()) { log.debug("Closing JDBC Connection [" + this.connection + "]"); } this.connection.close(); } } protected void openConnection() throws SQLException { if (log.isDebugEnabled()) { log.debug("Opening JDBC Connection"); } this.connection = this.dataSource.getConnection(); if (this.level != null) { this.connection.setTransactionIsolation(this.level.getLevel()); } } } </syntaxhighlight> === sqlSession.selectOne === 由sqlSession中<syntaxhighlight lang="java" inline>User user = sqlSession.selectOne("test.findUserById", 1);</syntaxhighlight>:(即“DefaultSqlSession.selectOne(String statement, Object parameter)”) <syntaxhighlight lang="java" line highlight="7,15,27,34"> package org.apache.ibatis.session.defaults; public class DefaultSqlSession implements SqlSession { ... public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) { this.configuration = configuration; this.executor = executor; this.dirty = false; this.autoCommit = autoCommit; } ... public <T> T selectOne(String statement, Object parameter) { // Popular vote was to return null on 0 results and throw exception on too many. List<T> list = this.<T>selectList(statement, parameter); if (list.size() == 1) { return list.get(0); } else if (list.size() > 1) { throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size()); } else { return null; } } ... public <E> List<E> selectList(String statement, Object parameter) { return this.selectList(statement, parameter, RowBounds.DEFAULT); } ... public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) { try { MappedStatement ms = configuration.getMappedStatement(statement); List<E> result = executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); return result; } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } </syntaxhighlight> * selectOne也是由selectList实现,“list.size() > 1”则抛出异常 * 操作数据库由executor实现 * 默认的executor是“SimpleExecutor” *: (继承自抽象类BaseExecutor): *: <syntaxhighlight lang="java" line highlight="10,27,45,48,51,54-62,69,80-87"> package org.apache.ibatis.executor; ... public abstract class BaseExecutor implements Executor { ... public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { BoundSql boundSql = ms.getBoundSql(parameter); CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql); return query(ms, parameter, rowBounds, resultHandler, key, boundSql); } @SuppressWarnings("unchecked") public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId()); if (closed) throw new ExecutorException("Executor was closed."); if (queryStack == 0 && ms.isFlushCacheRequired()) { clearLocalCache(); } List<E> list; try { queryStack++; list = resultHandler == null ? (List<E>) localCache.getObject(key) : null; if (list != null) { handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); } else { list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); } } finally { queryStack--; } if (queryStack == 0) { for (DeferredLoad deferredLoad : deferredLoads) { deferredLoad.load(); } deferredLoads.clear(); // issue #601 if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) { clearLocalCache(); // issue #482 } } return list; } ... protected abstract int doUpdate(MappedStatement ms, Object parameter) throws SQLException; protected abstract List<BatchResult> doFlushStatements(boolean isRollback) throws SQLException; protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException; protected void closeStatement(Statement statement) { if (statement != null) { try { statement.close(); } catch (SQLException e) { // ignore } } } ... private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { List<E> list; localCache.putObject(key, EXECUTION_PLACEHOLDER); try { list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql); } finally { localCache.removeObject(key); } localCache.putObject(key, list); if (ms.getStatementType() == StatementType.CALLABLE) { localOutputParameterCache.putObject(key, parameter); } return list; } protected Connection getConnection(Log statementLog) throws SQLException { Connection connection = transaction.getConnection(); if (statementLog.isDebugEnabled()) { return ConnectionLogger.newInstance(connection, statementLog, queryStack); } else { return connection; } } </syntaxhighlight> *# “doQuery(ms, parameter, rowBounds, resultHandler, boundSql)”等方法在实现类中实现(如:BatchExecutor、ReuseExecutor、SimpleExecutor); *# “getConnection(Log statementLog)”用于(使用transaction)获取链接,在BatchExecutor的 prepareStatement 方法中调用; *# “closeStatement(Statement statement)”用于关闭链接:在在BatchExecutor的 doQuery 等方法中调用; ** [[Mybatis源码:BaseExecutor解析]]
返回至“
入门:入门程序代码追踪
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息