前面一篇文章我们详细分析了SqlSessionFactory的创建过程,既然SqlSessionFactory有了,那么我们就可以通过sqlSessionFactory.openSession()来开启一个会话了,进而实现对数据库的操作,那么sqlSessionFactory.openSession()到底干了哪些事情呢?本篇文章就来详细了解一下。
SqlSession是Mybatis的高级接口,类似于JDBC操作的connection对象,它包装了数据库连接,通过这个接口我们可以实现增删改查,提交/回滚事务,关闭连接,获取代理类等操作。SqlSession是线程不安全的,每个线程都会有自己唯一的SqlSession,不同线程间调用同一个SqlSession会出现问题,因此在使用完后需要及时关闭。
SqlSession是个接口,其默认实现是DefaultSqlSession,另外一个子类是SqlSessionManager。
以下是SqlSession常见的方法:
public interface SqlSession extends Closeable {
/**
* 查询一个结果对象
**/
<T> T selectOne(String statement, Object parameter);
/**
* 查询一个结果集合
**/
<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
/**
* 查询一个map
**/
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
/**
* 查询游标
**/
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);
void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
/**
* 插入
**/
int insert(String statement, Object parameter);
/**
* 修改
**/
int update(String statement, Object parameter);
/**
* 删除
**/
int delete(String statement, Object parameter);
/**
* 提交事物
**/
void commit(boolean force);
/**
* 回滚事物
**/
void rollback(boolean force);
List<BatchResult> flushStatements();
void close();
void clearCache();
Configuration getConfiguration();
/**
* 获取映射代理类
**/
<T> T getMapper(Class<T> type);
/**
* 获取数据库连接
**/
Connection getConnection();
}
可以看到,SqlSession可以实现增删改查,提交/回滚事务,关闭连接,获取代理类等操作,下面就来看下SqlSession详细的创建过程。
SqlSession sqlSession = sqlSessionFactory.openSession()
通过sqlSessionFactory的openSession()开启一个会话。
DefaultSqlSessionFactory中有两种创建会话的方式:
//默认使用的是DefaultSqlSessionFactory
//org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()
@Override
public SqlSession openSession() {
//configuration中有默认执行器类型,是SIMPLE简单类型执行器(SimpleExecutor)
//从数据库连接池中获取一个连接,然后包装成一个SqlSession对像
//可以复用数据库连接
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
这里我们以openSessionFromDataSource为例:从数据源连接池获取一个SqlSession会话
//org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
//事务对象
Transaction tx = null;
try {
//从configuration对象中获取到我们之前解析的environment环境信息
final Environment environment = configuration.getEnvironment();
//事务工厂,这里是JbdcTransactionFactory工厂类
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//通过事务工厂创建JbdcTransaction事务,传入数据源等信息
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//创建Executor执行器
final Executor executor = configuration.newExecutor(tx, execType);
//创建DefaultSqlSession会话,传入Configuration、Executor对象
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主要需要下面几个东西:
环境对象,这是在mybatis-config.xml中配置的,主要用来生成TransactionFactory,而TransactionFactory是用来生成Transaction事务的。
事务对象,我们都知道sql执行时涉及到事务,需要提交或回滚什么的。创建Transaction事务对象,需要传入我们在mybatis-config.xml中配置的数据源信息(从environment获取,因为之前解析XML的时候保存进去了),通过这些参数,transactionFactory就可以生成Transaction。
执行器,它是一个接口,是Mybatis的核心执行器,相当于jdbc中的statement,发送sql语句并执行。executor的继承图如下所示,默认使用的是SimpleExecutor简单类型的执行器。
全局配置信息
我们Debug一下,查看具体创建过程各个属性的值:
至此,我们的SqlSession对象就创建成功了,其中还涉及到Executor执行器的创建过程,暂且先跳过,后面专门使用一篇文章分析Executor的原理。
openSessionFromDataSource 主要经历了以下几步:
本篇文章主要总结了Mybatis中SqlSession会话的创建过程,相信大家对SqlSession已经有了比较全面的了解。鉴于笔者水平有限,如果文章有什么错误或者需要补充的,希望小伙伴们指出来,希望这篇文章对大家有帮助。