【MyBatis源码】SqlSession实例创建过程
在MyBatis中,openSession()方法是开启数据库会话的入口,主要作用是生成SqlSession对象。我们从SqlSessionFactory接口入手,其实现类DefaultSqlSessionFactory的openSession()方法用于创建SqlSession实例.
SqlSessionFactory接口方法
public interface SqlSessionFactory {
public interface SqlSessionFactory {
/**
* 打开一个默认的SqlSession会话,一般使用默认配置创建SqlSession,通常是非自动提交模式。
*/
SqlSession openSession();
/**
* 打开一个新的SqlSession,并指定是否自动提交事务。
* autoCommit为true时会自动提交;为false时需要手动提交或回滚事务。
*/
SqlSession openSession(boolean autoCommit);
/**
* 使用已有的数据库连接Connection创建一个SqlSession。
* 这种方式适用于已有连接池或自定义数据库连接的情况。
*/
SqlSession openSession(Connection connection);
/**
*根据指定的事务隔离级别TransactionIsolationLevel创建SqlSession,可用于控制事务的隔离级别
*/
SqlSession openSession(TransactionIsolationLevel level);
/**
*根据指定的执行器类型ExecutorType创建SqlSession。ExecutorType可以是以下几种:
*
* SIMPLE:简单的执行器,每次执行语句都会创建一个新的预处理语句。
* REUSE:重用执行器,重用预处理语句。
* BATCH:批量执行的执行器,可以提高批量插入、更新的效率。
*/
SqlSession openSession(ExecutorType execType);
}
DefaultSqlSessionFactory
DefaultSqlSessionFactory类是MyBatis中SqlSessionFactory接口的默认实现类,用于创建和管理SqlSession对象。它是MyBatis连接数据库、执行SQL语句的核心组件之一,通常是通过读取配置文件并加载环境、数据源等设置来创建合适的数据库会话。
DefaultSqlSessionFactory主要负责:
- 管理数据库会话SqlSession的创建:提供多种重载的openSession方法,可以根据不同参数创建自定义的会话。
- 加载MyBatis的配置信息:在初始化时读取Configuration对象,并从中获取数据库环境、事务管理、执行器类型等信息。
- 提供配置访问:通过getConfiguration()方法,用户可以获取Configuration实例,从而查看或操作配置信息。
openSessionFromDataSource方法说明
openSessionFromDataSource方法是DefaultSqlSessionFactory类中创建SqlSession的关键方法之一。它负责从数据源中获取数据库连接,配置事务、执行器等,最终生成SqlSession对象
@Override
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
// 从configuration对象获取环境配置信息
final Environment environment = configuration.getEnvironment();
// 获取事务工厂对象,通过Environment获取相应的事务工厂,用于创建Transaction事务对象。TransactionFactory的具体实现通常根据MyBatis配置确定,比如可以是JdbcTransactionFactory或ManagedTransactionFactory等。
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
// 构建事务对象
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
// 创建执行器对象,Executor是MyBatis执行SQL语句的核心组件,根据传入的ExecutorType创建不同类型的执行器(如SIMPLE、REUSE、BATCH),从而控制SQL执行的模式。
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()用于重置MyBatis的错误上下文信息,确保每次操作都在独立的上下文中进行。
ErrorContext.instance().reset();
}
}
Executor接口结构
MyBatis提供了3种不同的Executor,分别为SimpleExecutor、ResueExecutor、BatchExecutor,这些Executor都继承至BaseExecutor,BaseExecutor中定义的方法的执行流程及通用的处理逻辑,具体的方法由子类来实现,是典型的模板方法模式的应用。SimpleExecutor是基础的Executor,能够完成基本的增删改查操作,ResueExecutor对JDBC中的Statement对象做了缓存,当执行相同的SQL语句时,直接从缓存中取出Statement对象进行复用,避免了频繁创建和销毁Statement对象,从而提升系统性能,这是享元思想的应用。BatchExecutor则会对调用同一个Mapper执行的update、insert和delete操作,调用Statement对象的批量操作功能。另外,我们知道MyBatis支持一级缓存和二级缓存,当MyBatis开启了二级缓存功能时,会使用CachingExecutor对SimpleExecutor、ResueExecutor、BatchExecutor进行装饰,为查询操作增加二级缓存功能,这是装饰器模式的应用。