Mybatis的SqlSession解析

在前文中,Mybatis使用教程中,有下面一段代码:
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;
总结:
[color=blue]DefaultSqlSessionFactory根据执行器类型,事务级别,是否提交等信息,来构建执行器Executor,然后根据执行器和configuration构建SqlSession,默认为DefaultSqlSession,从DefaultSqlSession的类信息方法来看,DefaultSqlSession的
查询则委托给executor的query,插入,更新,删除,则委托给executor的update,提交,回滚,清除缓存,刷新Statement,关闭SqlSession,都是委托给Executor的相应方法。下面一节我们来Executor。[/color]

//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, 8);
$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;
}

你可能感兴趣的:(Mybatis)