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;
总结:
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;
}

猜你喜欢

转载自donald-draper.iteye.com/blog/2339014