一、SqlSessionFactory
前两章我们已经介绍了如何解析mybatis-config.xml
和mapper
文件,同时也生成了我们的全局配置对象configuration
,那么就通过SqlSessionFactoryBuilder
创建了一个DefaultSqlSessionFactory
返回
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
// 读取配置文件
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
// build()
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
// 创建DefaultSqlSessionFactory
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
DefaultSqlSessionFactory
类实现了SqlSessionFactory
接口,接下来我们通过其openSession()
方法来创建SqlSession
,一个session就对应JDBC底层连接的一个对象
SqlSessionFactory
public interface SqlSessionFactory {
// 默认设置
SqlSession openSession();
// 自动提交模式
SqlSession openSession(boolean autoCommit);
// 特定的jdbc连接
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);
Configuration getConfiguration();
}
DefaultSqlSessionFactory
public class DefaultSqlSessionFactory implements SqlSessionFactory {
// 配置对象
private final Configuration configuration;
// 构造方法
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
// 创建sqlSession
@Override
public SqlSession openSession() {
// 调用的是另外一个openSessionFromDataSource方法
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
@Override
public SqlSession openSession(boolean autoCommit) {
//调用的是另外一个openSessionFromDataSource方法
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
}
// 省略一些代码...
// 在这个类里面有很多openSession的重载方法,都是调用的该方法
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);
// 构建一个executor来执行SQL
final Executor executor = configuration.newExecutor(tx, execType);
// 创建一个DefaultSqlSession返回
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 TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
// 如果环境为空 则创建ManagedTransactionFactory 代表事务由框架管理
if (environment == null || environment.getTransactionFactory() == null) {
return new ManagedTransactionFactory();
}
// 否则从环境中获取
return environment.getTransactionFactory();
}
3.创建SqlSession
SqlSession
上文我们介绍了通过DefaultSqlSessionFactory
将事务和执行器封装,创建DefaultSqlSession
对象,那么接下来我们就看一下
public interface SqlSession extends Closeable {
// 查询一个
<T> T selectOne(String statement);
<T> T selectOne(String statement, Object parameter);
// 查询列表
<E> List<E> selectList(String statement);
<E> List<E> selectList(String statement, Object parameter);
// 分页查询列表
<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
// 查询集合
<K, V> Map<K, V> selectMap(String statement, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
//分页查询集合
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
<T> Cursor<T> selectCursor(String statement);
<T> Cursor<T> selectCursor(String statement, Object parameter);
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);
void select(String statement, Object parameter, ResultHandler handler);
void select(String statement, ResultHandler handler);
void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
// 添加
int insert(String statement);
int insert(String statement, Object parameter);
int update(String statement);
int update(String statement, Object parameter);
// 删除
int delete(String statement);
int delete(String statement, Object parameter);
// 提交
void commit();
void commit(boolean force);
// 回滚
void rollback();
void rollback(boolean force);
List<BatchResult> flushStatements();
@Override
void close();
void clearCache();
Configuration getConfiguration();
// 获取Mapper
<T> T getMapper(Class<T> type);
Connection getConnection();
}
DefaultSqlSession
public class DefaultSqlSession implements SqlSession {
// 配置
private final Configuration configuration;
// 执行器
private final Executor executor;
// 自动提交
private final boolean autoCommit;
private boolean dirty;
// 游标集合
private List<Cursor<?>> cursorList;
// 构造方法
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
this.configuration = configuration;
this.executor = executor;
this.dirty = false;
this.autoCommit = autoCommit;
}
public DefaultSqlSession(Configuration configuration, Executor executor) {
this(configuration, executor, false);
}
@Override
public <T> T selectOne(String statement) {
return this.<T>selectOne(statement, null);
}
// 查询单个
@Override
public <T> T selectOne(String statement, Object parameter) {
// Popular vote was to return null on 0 results and throw exception on too many.
// 查询集合 判断长度是1
List<T> list = this.<T>selectList(statement, parameter);
if (list.size() == 1) {
return list.get(0);
} else if (list.size() > 1) {
throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
} else {
return null;
}
}
@Override
public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
return this.selectMap(statement, null, mapKey, RowBounds.DEFAULT);
}
@Override
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
return this.selectMap(statement, parameter, mapKey, RowBounds.DEFAULT);
}
// 查询Map
@Override
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
// 查询集合 注意这里使用的 泛型上界通配符
final List<? extends V> list = selectList(statement, parameter, rowBounds);
// 创建Map处理器
final DefaultMapResultHandler<K, V> mapResultHandler = new DefaultMapResultHandler<K, V>(mapKey,
configuration.getObjectFactory(), configuration.getObjectWrapperFactory(), configuration.getReflectorFactory());
final DefaultResultContext<V> context = new DefaultResultContext<V>();
// 通过遍历将集合封装到Map里面
for (V o : list) {
// 赋值到结果集的下一个结果中
context.nextResultObject(o);
// 取出结果对象,并添加到mapResultHandler内部维护的Map对象中
mapResultHandler.handleResult(context);
}
return mapResultHandler.getMappedResults();
}
@Override
public <T> Cursor<T> selectCursor(String statement) {
return selectCursor(statement, null);
}
@Override
public <T> Cursor<T> selectCursor(String statement, Object parameter) {
return selectCursor(statement, parameter, RowBounds.DEFAULT);
}
// 查询游标
@Override
public <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds) {
try {
MappedStatement ms = configuration.getMappedStatement(statement);
// 通过执行器执行
Cursor<T> cursor = executor.queryCursor(ms, wrapCollection(parameter), rowBounds);
// 将其添加到字段cursorList游标集合中
registerCursor(cursor);
return cursor;
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
@Override
public <E> List<E> selectList(String statement) {
return this.selectList(statement, null);
}
@Override
public <E> List<E> selectList(String statement, Object parameter) {
return this.selectList(statement, parameter, RowBounds.DEFAULT);
}
// 查询集合
@Override
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
try {
// 封装的DML标签
MappedStatement ms = configuration.getMappedStatement(statement);
// 执行器执行
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 void select(String statement, Object parameter, ResultHandler handler) {
select(statement, parameter, RowBounds.DEFAULT, handler);
}
@Override
public void select(String statement, ResultHandler handler) {
select(statement, null, RowBounds.DEFAULT, handler);
}
@Override
public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
try {
MappedStatement ms = configuration.getMappedStatement(statement);
executor.query(ms, wrapCollection(parameter), rowBounds, handler);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
@Override
public int insert(String statement) {
return insert(statement, null);
}
// 插入
@Override
public int insert(String statement, Object parameter) {
return update(statement, parameter);
}
@Override
public int update(String statement) {
return update(statement, null);
}
// 修改
@Override
public int update(String statement, Object parameter) {
try {
dirty = true;
MappedStatement ms = configuration.getMappedStatement(statement);
return executor.update(ms, wrapCollection(parameter));
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
// 删除
@Override
public int delete(String statement) {
return update(statement, null);
}
@Override
public int delete(String statement, Object parameter) {
return update(statement, parameter);
}
@Override
public void commit() {
commit(false);
}
@Override
public void commit(boolean force) {
try {
executor.commit(isCommitOrRollbackRequired(force));
dirty = false;
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
@Override
public void rollback() {
rollback(false);
}
@Override
public void rollback(boolean force) {
try {
executor.rollback(isCommitOrRollbackRequired(force));
dirty = false;
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error rolling back transaction. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
// 执行全部等待批处理语句,并将结果封装到BatchResult集合中
@Override
public List<BatchResult> flushStatements() {
try {
// 通知执行器执行全部等待批处理语句,并将结果封装到BatchResult集合中
return executor.flushStatements();
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error flushing statements. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
@Override
public void close() {
try {
executor.close(isCommitOrRollbackRequired(false));
closeCursors();
dirty = false;
} finally {
ErrorContext.instance().reset();
}
}
private void closeCursors() {
if (cursorList != null && cursorList.size() != 0) {
for (Cursor<?> cursor : cursorList) {
try {
cursor.close();
} catch (IOException e) {
throw ExceptionFactory.wrapException("Error closing cursor. Cause: " + e, e);
}
}
cursorList.clear();
}
}
@Override
public Configuration getConfiguration() {
return configuration;
}
@Override
public <T> T getMapper(Class<T> type) {
return configuration.<T>getMapper(type, this);
}
@Override
public Connection getConnection() {
try {
return executor.getTransaction().getConnection();
} catch (SQLException e) {
throw ExceptionFactory.wrapException("Error getting a new connection. Cause: " + e, e);
}
}
@Override
public void clearCache() {
executor.clearLocalCache();
}
private <T> void registerCursor(Cursor<T> cursor) {
if (cursorList == null) {
cursorList = new ArrayList<Cursor<?>>();
}
cursorList.add(cursor);
}
private boolean isCommitOrRollbackRequired(boolean force) {
return (!autoCommit && dirty) || force;
}
private Object wrapCollection(final Object object) {
if (object instanceof Collection) {
StrictMap<Object> map = new StrictMap<Object>();
map.put("collection", object);
if (object instanceof List) {
map.put("list", object);
}
return map;
} else if (object != null && object.getClass().isArray()) {
StrictMap<Object> map = new StrictMap<Object>();
map.put("array", object);
return map;
}
return object;
}
public static class StrictMap<V> extends HashMap<String, V> {
private static final long serialVersionUID = -5741767162221585340L;
@Override
public V get(Object key) {
if (!super.containsKey(key)) {
throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());
}
return super.get(key);
}
}
}
map = new StrictMap();
map.put(“array”, object);
return map;
}
return object;
}
public static class StrictMap extends HashMap<String, V> {
private static final long serialVersionUID = -5741767162221585340L;
@Override
public V get(Object key) {
if (!super.containsKey(key)) {
throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());
}
return super.get(key);
}
}
}