Mybatis的SqlSession解析
程序员文章站
2022-05-18 22:16:52
...
在前文中,Mybatis使用教程中,有下面一段代码:
首先我们来看这一句
而sqlSessionFactory默认为DefaultSqlSessionFactory
从DefaultSqlSessionFactory的方法,我们可以看出openSession实际上,是通过
openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)
其中ExecutorType为执行器类型,TransactionIsolationLevel为事务级别,autoCommit是否自动提交;
下面来看一下openSessionFromDataSource方法:
来看这一句
//根据environment获取事务工厂
再看这一句
//根据数据源,事务级别,是否自动提交,创建事务
//JdbcTransaction
事务看完,我们来看一下
//根据数据源,事务级别,是否自动提交,创建执行器
//Configuration
从上面configuration的创建执行器方法,可以看出执行器有BatchExecutor,ReuseExecutor,SimpleExecutor
根据执行器类型,创建执行器,如果缓存启用,则包装executor为CachingExecutor;
//BatchExecutor
//SimpleExecutor
//CachingExecutor
//BaseExecutor
现在回到DefaultSqlSessionFactory的方法过openSessionFromDataSource
//根据配置和executor构建DefaultSqlSession
//DefaultSqlSession
从DefaultSqlSession方法可以看出,查询则委托给executor的query,插入,更新,删除,则委托给executor的update;
总结:
DefaultSqlSessionFactory根据执行器类型,事务级别,是否提交等信息,来构建执行器Executor,然后根据执行器和configuration构建SqlSession,默认为DefaultSqlSession,从DefaultSqlSession的类信息方法来看,DefaultSqlSession的
查询则委托给executor的query,插入,更新,删除,则委托给executor的update,提交,回滚,清除缓存,刷新Statement,关闭SqlSession,都是委托给Executor的相应方法。下面一节我们来Executor。
//ExecutorType
public final class ExecutorType extends Enum
{
private ExecutorType(String s, int i)
{
super(s, i);
}
public static final ExecutorType SIMPLE;
public static final ExecutorType REUSE;
public static final ExecutorType BATCH;
static
{
SIMPLE = new ExecutorType("SIMPLE", 0);
REUSE = new ExecutorType("REUSE", 1);
BATCH = new ExecutorType("BATCH", 2);
$VALUES = (new ExecutorType[] {
SIMPLE, REUSE, BATCH
});
}
}
//TransactionIsolationLevel
public final class TransactionIsolationLevel extends Enum
{
public static TransactionIsolationLevel valueOf(String name)
{
return (TransactionIsolationLevel)Enum.valueOf(org/apache/ibatis/session/TransactionIsolationLevel, name);
}
private TransactionIsolationLevel(String s, int i, int level)
{
super(s, i);
this.level = level;
}
public int getLevel()
{
return level;
}
public static final TransactionIsolationLevel NONE;
public static final TransactionIsolationLevel READ_COMMITTED;
public static final TransactionIsolationLevel READ_UNCOMMITTED;
public static final TransactionIsolationLevel REPEATABLE_READ;
public static final TransactionIsolationLevel SERIALIZABLE;
private final int level;
private static final TransactionIsolationLevel $VALUES[];
static
{
NONE = new TransactionIsolationLevel("NONE", 0, 0);
READ_COMMITTED = new TransactionIsolationLevel("READ_COMMITTED", 1, 2);
READ_UNCOMMITTED = new TransactionIsolationLevel("READ_UNCOMMITTED", 2, 1);
REPEATABLE_READ = new TransactionIsolationLevel("REPEATABLE_READ", 3, 4);
SERIALIZABLE = new TransactionIsolationLevel("SERIALIZABLE", 4,;
$VALUES = (new TransactionIsolationLevel[] {
NONE, READ_COMMITTED, READ_UNCOMMITTED, REPEATABLE_READ, SERIALIZABLE
});
}
}
//Executor
public interface Executor
{
public abstract int update(MappedStatement mappedstatement, Object obj)
throws SQLException;
public abstract List query(MappedStatement mappedstatement, Object obj, RowBounds rowbounds, ResultHandler resulthandler, CacheKey cachekey, BoundSql boundsql)
throws SQLException;
public abstract List query(MappedStatement mappedstatement, Object obj, RowBounds rowbounds, ResultHandler resulthandler)
throws SQLException;
public abstract List flushStatements()
throws SQLException;
public abstract void commit(boolean flag)
throws SQLException;
public abstract void rollback(boolean flag)
throws SQLException;
public abstract CacheKey createCacheKey(MappedStatement mappedstatement, Object obj, RowBounds rowbounds, BoundSql boundsql);
public abstract boolean isCached(MappedStatement mappedstatement, CacheKey cachekey);
public abstract void clearLocalCache();
public abstract void deferLoad(MappedStatement mappedstatement, MetaObject metaobject, String s, CacheKey cachekey, Class class1);
public abstract Transaction getTransaction();
public abstract void close(boolean flag);
public abstract boolean isClosed();
public static final ResultHandler NO_RESULT_HANDLER = null;
}
SqlSession session = sqlSessionFactory.openSession(); try { User u1 = new User(); u1.setAge(12); u1.setName("donald"); session.insert("test.Dao.UserMapper.insert", u1); User u2 = session.selectOne("test.Dao.UserMapper.selectByPrimaryKey", u1.getId()); System.out.println("======u1:"+JsonUtil.toJson(u2)); User u3 = new User(); u3.setAge(30); u3.setName("jamel"); session.insert("test.Dao.UserMapper.insert", u3); User u4 = session.selectOne("test.Dao.UserMapper.selectByPrimaryKey", u3.getId()); System.out.println("======u3:"+JsonUtil.toJson(u4)); // session.flushStatements(); session.commit(); u3.setName("rain"); session.update("test.Dao.UserMapper.updateByPrimaryKeySelective", u3); // session.commit(); User u5 = session.selectOne("test.Dao.UserMapper.selectByPrimaryKey", u3.getId()); System.out.println("======cache-u3-name:"+u5.getName()); } catch(Exception e){ e.printStackTrace(); } finally { session.close(); }
首先我们来看这一句
SqlSession session = sqlSessionFactory.openSession();
而sqlSessionFactory默认为DefaultSqlSessionFactory
//DefaultSqlSessionFactory public class DefaultSqlSessionFactory implements SqlSessionFactory { public DefaultSqlSessionFactory(Configuration configuration) { this.configuration = configuration; } public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); } public SqlSession openSession(boolean autoCommit) { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit); } public SqlSession openSession(ExecutorType execType) { return openSessionFromDataSource(execType, null, false); } public SqlSession openSession(TransactionIsolationLevel level) { return openSessionFromDataSource(configuration.getDefaultExecutorType(), level, false); } public SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level) { return openSessionFromDataSource(execType, level, false); } public SqlSession openSession(ExecutorType execType, boolean autoCommit) { return openSessionFromDataSource(execType, null, autoCommit); } public SqlSession openSession(Connection connection) { return openSessionFromConnection(configuration.getDefaultExecutorType(), connection); } public SqlSession openSession(ExecutorType execType, Connection connection) { return openSessionFromConnection(execType, connection); } private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { // } private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) { } }
从DefaultSqlSessionFactory的方法,我们可以看出openSession实际上,是通过
openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)
其中ExecutorType为执行器类型,TransactionIsolationLevel为事务级别,autoCommit是否自动提交;
下面来看一下openSessionFromDataSource方法:
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; DefaultSqlSession defaultsqlsession; try { //从configuration获取environment Environment environment = configuration.getEnvironment(); //根据environment获取事务工厂 TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); //根据数据源,事务级别,是否自动提交,创建事务 tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); //根据数据源,事务级别,是否自动提交,创建执行器 org.apache.ibatis.executor.Executor executor = configuration.newExecutor(tx, execType, autoCommit); //根据配置和executor构建DefaultSqlSession defaultsqlsession = new DefaultSqlSession(configuration, executor); } catch(Exception e) { closeTransaction(tx); throw ExceptionFactory.wrapException((new StringBuilder()).append("Error opening session. Cause: ").append(e).toString(), e); } }
来看这一句
//根据environment获取事务工厂
TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) { if(environment == null || environment.getTransactionFactory() == null) return new ManagedTransactionFactory(); else //从environment获取事务工厂,JdbcTransactionFactory或PooledDataSourceFactory return environment.getTransactionFactory(); }
再看这一句
//根据数据源,事务级别,是否自动提交,创建事务
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); //JdbcTransactionFactory public class JdbcTransactionFactory implements TransactionFactory { //根据数据源,事务级别,是否自动提交,创建事务 public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) { return new JdbcTransaction(ds, level, autoCommit); } }
//JdbcTransaction
public class JdbcTransaction implements Transaction { protected Connection connection;//数据库连接 protected DataSource dataSource;//数据源 protected TransactionIsolationLevel level;//事务级别 protected boolean autoCommmit; public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) { dataSource = ds; level = desiredLevel; autoCommmit = desiredAutoCommit; } //获取Connection public Connection getConnection() throws SQLException { if(connection == null) openConnection(); return connection; } //打开Connection protected void openConnection() throws SQLException { if(log.isDebugEnabled()) log.debug("Openning JDBC Connection"); connection = dataSource.getConnection(); if(level != null) //设置连接事务级别 connection.setTransactionIsolation(level.getLevel()); setDesiredAutoCommit(autoCommmit); } //提交事务 public void commit() throws SQLException { if(connection != null && !connection.getAutoCommit()) { if(log.isDebugEnabled()) log.debug((new StringBuilder()).append("Committing JDBC Connection [").append(connection).append("]").toString()); connection.commit(); } } //回滚事务 public void rollback() throws SQLException { if(connection != null && !connection.getAutoCommit()) { if(log.isDebugEnabled()) log.debug((new StringBuilder()).append("Rolling back JDBC Connection [").append(connection).append("]").toString()); connection.rollback(); } } //关闭事务 public void close() throws SQLException { if(connection != null) { resetAutoCommit(); if(log.isDebugEnabled()) log.debug((new StringBuilder()).append("Closing JDBC Connection [").append(connection).append("]").toString()); connection.close(); } } }
事务看完,我们来看一下
//根据数据源,事务级别,是否自动提交,创建执行器
org.apache.ibatis.executor.Executor executor = configuration.newExecutor(tx, execType, autoCommit);
//Configuration
public Executor newExecutor(Transaction transaction, ExecutorType executorType, boolean autoCommit) { executorType = executorType != null ? executorType : defaultExecutorType; executorType = executorType != null ? executorType : ExecutorType.SIMPLE; Executor executor; if(ExecutorType.BATCH == executorType) executor = new BatchExecutor(this, transaction); else if(ExecutorType.REUSE == executorType) executor = new ReuseExecutor(this, transaction); else executor = new SimpleExecutor(this, transaction); if(cacheEnabled) executor = new CachingExecutor(executor, autoCommit); //将执行器插入到拦截器链中 executor = (Executor)interceptorChain.pluginAll(executor); return executor; }
从上面configuration的创建执行器方法,可以看出执行器有BatchExecutor,ReuseExecutor,SimpleExecutor
根据执行器类型,创建执行器,如果缓存启用,则包装executor为CachingExecutor;
//BatchExecutor
public class BatchExecutor extends BaseExecutor { public static final int BATCH_UPDATE_RETURN_VALUE = -2147482646; private final List statementList = new ArrayList(); private final List batchResultList = new ArrayList(); private String currentSql; private MappedStatement currentStatement; public BatchExecutor(Configuration configuration, Transaction transaction) { super(configuration, transaction); } }
//SimpleExecutor
public class SimpleExecutor extends BaseExecutor { public SimpleExecutor(Configuration configuration, Transaction transaction) { super(configuration, transaction); } }
//CachingExecutor
public class CachingExecutor implements Executor { private Executor _flddelegate;//代理执行器 private boolean autoCommit; private TransactionalCacheManager tcm; private boolean dirty; public CachingExecutor(Executor delegate, boolean autoCommit) { tcm = new TransactionalCacheManager(); _flddelegate = delegate; this.autoCommit = autoCommit; } }
//BaseExecutor
public abstract class BaseExecutor implements Executor { private static final Log log = LogFactory.getLog(org/apache/ibatis/executor/BaseExecutor); protected Transaction transaction; protected ConcurrentLinkedQueue deferredLoads; protected PerpetualCache localCache; protected PerpetualCache localOutputParameterCache; protected Configuration configuration; protected int queryStack; private boolean closed; //构造BaseExecutor protected BaseExecutor(Configuration configuration, Transaction transaction) { queryStack = 0; this.transaction = transaction; deferredLoads = new ConcurrentLinkedQueue(); localCache = new PerpetualCache("LocalCache"); localOutputParameterCache = new PerpetualCache("LocalOutputParameterCache"); closed = false; this.configuration = configuration; } //获取Connection protected Connection getConnection(Log statementLog) throws SQLException { Connection connection = transaction.getConnection(); if(statementLog.isDebugEnabled()) return ConnectionLogger.newInstance(connection, statementLog); else return connection; } //提交 public void commit(boolean required) throws SQLException { if(closed) throw new ExecutorException("Cannot commit, transaction is already closed"); clearLocalCache(); flushStatements(); if(required) transaction.commit(); } public List flushStatements() throws SQLException { return flushStatements(false); } public List flushStatements(boolean isRollBack) throws SQLException { if(closed) throw new ExecutorException("Executor was closed."); else return doFlushStatements(isRollBack); } //待子类扩展 protected abstract List doFlushStatements(boolean flag) throws SQLException; //回滚 public void rollback(boolean required) throws SQLException { if(closed) break MISSING_BLOCK_LABEL_49; clearLocalCache(); flushStatements(true); if(required) transaction.rollback(); break MISSING_BLOCK_LABEL_49; Exception exception; exception; if(required) transaction.rollback(); throw exception; } //清除本地缓存 public void clearLocalCache() { if(!closed) { localCache.clear(); localOutputParameterCache.clear(); } } //更新 public int update(MappedStatement ms, Object parameter) throws SQLException { ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId()); if(closed) { throw new ExecutorException("Executor was closed."); } else { //首先清除缓存 clearLocalCache(); //委托给doUpdate return doUpdate(ms, parameter); } } //带子类扩展 protected abstract int doUpdate(MappedStatement mappedstatement, Object obj) throws SQLException; //查询 public List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId()); if(closed) throw new ExecutorException("Executor was closed."); if(queryStack == 0 && ms.isFlushCacheRequired()) //如果queryStack为0,且需要刷新缓存,则清除本地缓存 clearLocalCache(); List list; queryStack++; list = resultHandler != null ? null : (List)localCache.getObject(key); if(list != null) //从本地获取查询结果 handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); else //从数据库查询结果 list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); queryStack--; break MISSING_BLOCK_LABEL_152; Exception exception; exception; queryStack--; throw exception; if(queryStack == 0) { DeferredLoad deferredLoad; for(Iterator i$ = deferredLoads.iterator(); i$.hasNext(); deferredLoad.load()) deferredLoad = (DeferredLoad)i$.next(); deferredLoads.clear(); if(configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) clearLocalCache(); } return list; } //从数据库查询结果 private List queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { localCache.putObject(key, ExecutionPlaceholder.EXECUTION_PLACEHOLDER); //将查询委托给doQuery List list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql); localCache.removeObject(key); break MISSING_BLOCK_LABEL_53; Exception exception; exception; localCache.removeObject(key); throw exception; localCache.putObject(key, list); if(ms.getStatementType() == StatementType.CALLABLE) localOutputParameterCache.putObject(key, parameter); return list; } //待子类扩展 protected abstract List doQuery(MappedStatement mappedstatement, Object obj, RowBounds rowbounds, ResultHandler resulthandler, BoundSql boundsql) throws SQLException; }
现在回到DefaultSqlSessionFactory的方法过openSessionFromDataSource
//根据配置和executor构建DefaultSqlSession
defaultsqlsession = new DefaultSqlSession(configuration, executor);
//DefaultSqlSession
public class DefaultSqlSession implements SqlSession { private Configuration configuration; private Executor executor; private boolean dirty; public DefaultSqlSession(Configuration configuration, Executor executor) { this.configuration = configuration; this.executor = executor; dirty = false; } //查询 public Object selectOne(String statement) { return selectOne(statement, null); } public Object selectOne(String statement, Object parameter) { List list = selectList(statement, parameter); if(list.size() == 1) return list.get(0); if(list.size() > 1) throw new TooManyResultsException((new StringBuilder()).append("Expected one result (or null) to be returned by selectOne(), but found: ").append(list.size()).toString()); else return null; } public List selectList(String statement) { return selectList(statement, null); } public List selectList(String statement, Object parameter) { return selectList(statement, parameter, RowBounds.DEFAULT); } public List selectList(String statement, Object parameter, RowBounds rowBounds) { List list; try { org.apache.ibatis.mapping.MappedStatement ms = configuration.getMappedStatement(statement); //调用executor的查询方法 List result = executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); list = result; } } //插入 public int insert(String statement) { return insert(statement, null); } public int insert(String statement, Object parameter) { //委托给update方法 return update(statement, parameter); } public int update(String statement) { return update(statement, null); } public int update(String statement, Object parameter) { int i; try { dirty = true; org.apache.ibatis.mapping.MappedStatement ms = configuration.getMappedStatement(statement); //委托给executor的update i = executor.update(ms, wrapCollection(parameter)); } } //删除 public int delete(String statement) { //委托给update return update(statement, null); } public int delete(String statement, Object parameter) { return update(statement, parameter); } //提交 public void commit() { commit(false); } public void commit(boolean force) { try { //委托executor的commit executor.commit(isCommitOrRollbackRequired(force)); dirty = false; } } //回滚 public void rollback() { rollback(false); } public void rollback(boolean force) { try { //委托executor的rollback executor.rollback(isCommitOrRollbackRequired(force)); dirty = false; } } //清除缓存 public void clearCache() { ////委托executor的clearLocalCache executor.clearLocalCache(); } //刷新Statements public List flushStatements() { List list; try { //委托executor的flushStatements list = executor.flushStatements(); } } //关闭SqlSession public void close() { //委托executor的close executor.close(isCommitOrRollbackRequired(false)); dirty = false; } }
从DefaultSqlSession方法可以看出,查询则委托给executor的query,插入,更新,删除,则委托给executor的update;
总结:
DefaultSqlSessionFactory根据执行器类型,事务级别,是否提交等信息,来构建执行器Executor,然后根据执行器和configuration构建SqlSession,默认为DefaultSqlSession,从DefaultSqlSession的类信息方法来看,DefaultSqlSession的
查询则委托给executor的query,插入,更新,删除,则委托给executor的update,提交,回滚,清除缓存,刷新Statement,关闭SqlSession,都是委托给Executor的相应方法。下面一节我们来Executor。
//ExecutorType
public final class ExecutorType extends Enum
{
private ExecutorType(String s, int i)
{
super(s, i);
}
public static final ExecutorType SIMPLE;
public static final ExecutorType REUSE;
public static final ExecutorType BATCH;
static
{
SIMPLE = new ExecutorType("SIMPLE", 0);
REUSE = new ExecutorType("REUSE", 1);
BATCH = new ExecutorType("BATCH", 2);
$VALUES = (new ExecutorType[] {
SIMPLE, REUSE, BATCH
});
}
}
//TransactionIsolationLevel
public final class TransactionIsolationLevel extends Enum
{
public static TransactionIsolationLevel valueOf(String name)
{
return (TransactionIsolationLevel)Enum.valueOf(org/apache/ibatis/session/TransactionIsolationLevel, name);
}
private TransactionIsolationLevel(String s, int i, int level)
{
super(s, i);
this.level = level;
}
public int getLevel()
{
return level;
}
public static final TransactionIsolationLevel NONE;
public static final TransactionIsolationLevel READ_COMMITTED;
public static final TransactionIsolationLevel READ_UNCOMMITTED;
public static final TransactionIsolationLevel REPEATABLE_READ;
public static final TransactionIsolationLevel SERIALIZABLE;
private final int level;
private static final TransactionIsolationLevel $VALUES[];
static
{
NONE = new TransactionIsolationLevel("NONE", 0, 0);
READ_COMMITTED = new TransactionIsolationLevel("READ_COMMITTED", 1, 2);
READ_UNCOMMITTED = new TransactionIsolationLevel("READ_UNCOMMITTED", 2, 1);
REPEATABLE_READ = new TransactionIsolationLevel("REPEATABLE_READ", 3, 4);
SERIALIZABLE = new TransactionIsolationLevel("SERIALIZABLE", 4,;
$VALUES = (new TransactionIsolationLevel[] {
NONE, READ_COMMITTED, READ_UNCOMMITTED, REPEATABLE_READ, SERIALIZABLE
});
}
}
//Executor
public interface Executor
{
public abstract int update(MappedStatement mappedstatement, Object obj)
throws SQLException;
public abstract List query(MappedStatement mappedstatement, Object obj, RowBounds rowbounds, ResultHandler resulthandler, CacheKey cachekey, BoundSql boundsql)
throws SQLException;
public abstract List query(MappedStatement mappedstatement, Object obj, RowBounds rowbounds, ResultHandler resulthandler)
throws SQLException;
public abstract List flushStatements()
throws SQLException;
public abstract void commit(boolean flag)
throws SQLException;
public abstract void rollback(boolean flag)
throws SQLException;
public abstract CacheKey createCacheKey(MappedStatement mappedstatement, Object obj, RowBounds rowbounds, BoundSql boundsql);
public abstract boolean isCached(MappedStatement mappedstatement, CacheKey cachekey);
public abstract void clearLocalCache();
public abstract void deferLoad(MappedStatement mappedstatement, MetaObject metaobject, String s, CacheKey cachekey, Class class1);
public abstract Transaction getTransaction();
public abstract void close(boolean flag);
public abstract boolean isClosed();
public static final ResultHandler NO_RESULT_HANDLER = null;
}
上一篇: Redis源码剖析-dict字典
下一篇: java中的静态资源加载的实例详解