SqlSession理解
一、创建SqlSession
1.创建事务
a.事务工厂根据DataSource创建一个事务对象(Connection对象,事务级别,是否自动提交)
b.事务工厂根据Connection创建一个事务对象(事务级别和是否自动提交已经被设置在Connection对象中)
c.系统默认的事务工厂是ManagedTransactionFactory,默认是关闭连接的 private boolean closeConnection = true;
2.创建Executor(statement)对象
a.根据配置文件中的ExecutorType决定创建Executor的类型(SIMPLE【SimpleExecutor】, REUSE【ReuseExecutor】, BATCH【BatchExecutor】)
b.如果配置cacheEnabled=true,则创建executor = new CachingExecutor(executor);
3.返回SqlSession,默认返回的是DefaultSqlSession对象(该对象维护Configuration对象、Executor对象、是否自动提交)
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 SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
try {
boolean autoCommit;
try {
autoCommit = connection.getAutoCommit();
} catch (SQLException e) {
// Failover to true, as most poor drivers
// or databases won‘t support transactions
autoCommit = true;
}
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
final Transaction tx = transactionFactory.newTransaction(connection);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
二.DefaultSqlSession对象,SqlSession对象的使用
(一)在使用DefaultSqlSession之前要现要求Mapper.xml的加载过程
对mapper节点的解析,XMLMapperBuilder对象进行xml文件解析和MapperBuilderAssistant对象将解析后的数据组装成对象交付给Configuration对象
1.传递mapper.xml文件路径、inputstream、Configuration对象
2.XMLMapperBuilder对象的configurationElement(parser.evalNode("/mapper"));解析mpper.xml文件
3.XMLMapperBuilder对象以buildStatementFromContext(context.evalNodes("select|insert|update|delete"));为例进行分析
4.XMLMapperBuilder对象的buildStatementFromContext(List<XNode> list, String requiredDatabaseId),主要是XMLStatementBuilder对象在干活
5.final XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration, builderAssistant, context, requiredDatabaseId);
6.XMLStatementBuilder对象开始干活:statementParser.parseStatementNode();最终将所有的配置信息放到MapperBuilderAssistant对象中,然后由MapperBuilderAssistant把真实的MappedStatement放到Configuration对象中
(二)使用SqlSession的重要一步就是首先要根据ID获取MappedStatement
1.SqlSession session = sqlSessionFactory.openSession();
2.BoundBlogMapper mapper = session.getMapper(BoundBlogMapper.class);//真实是从Configuration对象中进行查找的
3.Blog b = mapper.selectSomething(1);
4.session.close();