MyBatis(2)SqlSession的工作原理
2017-09-23 14:22
435 查看
SqlSession对象的生成
SqlSession session = factory.openSession(); //=> @Override 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); //生成一个默认SqlSession,将配置,执行器传给他 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(); } }
使用SqlSession的selectList()和getMapper()
@Override public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) { try { //根据statement,在Configuration找到对应的MappedStatement MappedStatement ms = configuration.getMappedStatement(statement); //使用执行器来查询结果 //NO_RESULT_HANDLER是null return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } @Override public <T> T getMapper(Class<T> type) { return configuration.<T>getMapper(type, this); }
使用executor.query()方法
@Override public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { //得到绑定的SQL, BoundSql boundSql = ms.getBoundSql(parameter); //创建缓存Key CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql); //查询 return query(ms, parameter, rowBounds, resultHandler, key, boundSql); } @SuppressWarnings("unchecked") @Override 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."); } //先清缓存,再查询。 //仅当查询堆栈为0才清缓存,为了处理递归调用 if (queryStack == 0 && ms.isFlushCacheRequired()) { clearLocalCache(); } List<E> list; try { //这样递归调用到上面就不会清局部缓存了 queryStack++; list = resultHandler == null ? (List<E>) localCache.getObject(key) : null; if (list != null) { //若查到localCache缓存,则处理 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(); } // issue #601 deferredLoads.clear(); if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) { // issue #482 clearLocalCache(); } } return list; } 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; } @Override 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()); //用handler去处理查询语句,将结果用ResultHandler来处理。 return handler.<E>query(stmt, resultHandler); } finally { closeStatement(stmt); } }
相关文章推荐
- 【spring+mybatis】MyBatis-Spring-SqlSessionFactoryBean
- mybatis 3.4.2 DefaultSqlSessionFactory的优化版SqlSessionManager
- MyBatis原理第四篇——statementHandler对象(sqlSession内部核心实现,插件的基础)
- mybatis入门(一)-mybatis介绍和获取SqlSession
- mybatis源码分析(1)——SqlSessionFactory实例的产生过程
- mybatis-spring整合总结02_SqlSessionFactoryBean
- MyBatis学习总结(二)——SQLSessionFactory实例
- Spring3 整合MyBatis3 配置多数据源 动态切换 选择SqlSessionFactory
- MyBatis中如何通过继承SqlSessionDaoSupport来编写DAO(二) 推荐
- 通过SqlSessionTemplate基于模板类实现Mybatis
- mybatis中获取SqlSessionFactory的几种方法及其相关使用
- Mybatis SqlSessionFactory创建过程
- 重构Mybatis与Spring集成的SqlSessionFactoryBean(2)
- Mybatis SqlSessionTemplate 源码解析
- mybatis中SqlSessionFactoryBean路径配置错误
- (SqlSessionTemplate和SessionFactory)sqlsession的产生过程,hibernate和mybatis的对比
- spring-mybatis 之SqlSessionFactoryBean
- 3、关于利用SqlSessionFactoryBuilder去构建SqlSessionFactory,以及Mybatis的dao的实现
- getSqlSession().selectOne( , )出错问题以及mybatis的xml加载问题
- Mybatis学习(七)mybatis中的SqlSession使用的范围