欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Mybatis的SqlSession解析

程序员文章站 2022-05-18 22:16:52
...
在前文中,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,Mybatis的SqlSession解析
            
    
    博客分类: Mybatis MybaitsSqlSession ;
        $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;
}
相关标签: Mybaits SqlSession