1.入口
整个程序的demo在放一下:
public static void main(String[] args) {
//获取配置文件信息流
InputStream stream = Demo.class.getClassLoader().getResourceAsStream("mybatis.xml");
//使用SqlSessionFactory构建器,读取配置文件构建出一个sessionFactory
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);
//通过sessionFactory开启一个Session
SqlSession sqlSession = sessionFactory.openSession(true);
//调用selectOne方法查询数据
User user = sqlSession.selectOne("org.demo.bean.UserMapper.getUser", 1);
//输出
System.out.println(user);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user2 = mapper.getUser(1L);
System.out.println(user2);
}
第一步,通过读取配置文件构建一个SqlSessionFactory上文已经说过,这里看一下如何通过SqlSessionFactory构建一个session
2.sessionFactory.openSession
SqlSessionFactory中提供了多个openSession方法,如下:
SqlSession openSession();
SqlSession openSession(boolean autoCommit);
SqlSession openSession(Connection connection);
SqlSession openSession(TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType);
SqlSession openSession(ExecutorType execType, boolean autoCommit);
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType, Connection connection);
从上文中知道我们构建出来的SqlSessionFactory是一个DefaultSqlSessionFactory对象,那么我们来看一下DefaultSqlSessionFactory中是如何实现这个方法的:
/**
* openSession 调用openSessionFromDataSource方法执行
*/
@Override
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
@Override
public SqlSession openSession(boolean autoCommit) {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
}
@Override
public SqlSession openSession(ExecutorType execType) {
return openSessionFromDataSource(execType, null, false);
}
@Override
public SqlSession openSession(TransactionIsolationLevel level) {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), level, false);
}
@Override
public SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level) {
return openSessionFromDataSource(execType, level, false);
}
@Override
public SqlSession openSession(ExecutorType execType, boolean autoCommit) {
return openSessionFromDataSource(execType, null, autoCommit);
}
@Override
public SqlSession openSession(Connection connection) {
return openSessionFromConnection(configuration.getDefaultExecutorType(), connection);
}
@Override
public SqlSession openSession(ExecutorType execType, Connection connection) {
return openSessionFromConnection(execType, connection);
}
我们可以看到,这里主要是通过openSessionFromDataSource和openSessionFromConnection两个方法实现的,前者是通过DataSource数据源构建一个SqlSession,后者是通过一个Connection链接构建的SqlSession。
3.openSessionFromDataSource
我们详细看一下openSessionFromDataSource这个方法的实现
/**
* 开启一个session
* @param execType 执行器类型
* @param level 事务级别
* @param autoCommit 是否自动提交事务
* @return SqlSession
*/
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
//获取environment信息
final Environment environment = configuration.getEnvironment();
//根据environment获取对应事务工厂
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//创建一个新的事务
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//创建一个执行器 参数是一个事务,一个执行器类型
final Executor executor = configuration.newExecutor(tx, execType);
//创建DefaultSqlSession并给定参数configuration,executor,autoCommit
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();
}
}
3.1 参数解析
其中execType是指执行器的类型这里主要分三种,是用枚举来定义的
public enum ExecutorType {
SIMPLE, REUSE, BATCH
}
level是事务的隔离级别,这里也是通过枚举来定义的
public enum TransactionIsolationLevel {
NONE(Connection.TRANSACTION_NONE), //无事务
READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED), //读已提交
READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED), //读未提交
REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ), //可重复读
SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE); //串行化
private final int level;
TransactionIsolationLevel(int level) {
this.level = level;
}
public int getLevel() {
return level;
}
}
其具体的值是在Connection中定义的,而Connection是一个interface接口,参数默认是static类型的,所以才可以直接通过Connection类名获取对应值
int TRANSACTION_NONE = 0;
int TRANSACTION_READ_UNCOMMITTED = 1;
int TRANSACTION_READ_COMMITTED = 2;
int TRANSACTION_REPEATABLE_READ = 4;
int TRANSACTION_SERIALIZABLE = 8;
最后一个参数autoCommit代表是事务是否自动提交。
3.2 方法解析
1.获取environment信息
configuration是我们在构建SqlSessionFactory的时候读取配置文件生成的,具体参照上文。而getEnvironment方法就是获取其environment属性,对应xml中的environment节点:
public Environment getEnvironment() {
return environment;
}
2.根据environment获取对应事务工厂
直接上源码
/**
* 获取事务工厂
*/
private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
if (environment == null || environment.getTransactionFactory() == null) {
return new ManagedTransactionFactory(); //为空时默认返回ManagedTransactionFactory对象
}
return environment.getTransactionFactory(); //返回对应事务工厂
}
3.创建一个新的事务
这里看一下ManagedTransactionFactory中创建事务,就是直接创建对象,也没什么好说的
/**
* 创建一个事务
*/
@Override
public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
return new ManagedTransaction(ds, level, closeConnection);
}
public ManagedTransaction(DataSource ds, TransactionIsolationLevel level, boolean closeConnection) {
this.dataSource = ds;
this.level = level;
this.closeConnection = closeConnection;
}
4.创建一个执行器
这里就是根据类型创建不同的执行器对象,然后根据是否开启二级缓存的配置判断是否需要将执行器包装成CachingExecutor,最后返回执行器
/**
* 创建一个执行器
* @param transaction 事务
* @param executorType 执行器类型
*/
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
//若executorType为null 则设置成defaultExecutorType也就是ExecutorType.SIMPLE
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
//根据类型生成对应的执行器对象
if (ExecutorType.BATCH == executorType) { //BATCH类型
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) { //REUSE类型
executor = new ReuseExecutor(this, transaction);
} else { //默认的SIMPLE类型
executor = new SimpleExecutor(this, transaction);
}
if (cacheEnabled) { //是否开启缓存
//通过CachingExecutor对生成的执行器executor进行包装
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor; //返回执行器
}
CachingExecutor执行器只是对执行器进行了一个包装,其中有一个执行器的属性,对执行器的方法是新都是调用这个执行器属性来实现的,只不过在调用之前会先加上二级缓存相关的逻辑处理,其类定义如下:
public class CachingExecutor implements Executor {
private final Executor delegate;
private final TransactionalCacheManager tcm = new TransactionalCacheManager();
public CachingExecutor(Executor delegate) {
this.delegate = delegate;
delegate.setExecutorWrapper(this);
}
}
5.创建DefaultSqlSession
也就是new一个对象返回。