DefaultSqlSession第二讲-更新,刷新Statement

上一篇文章中,我们讲到DefaultSqlSession的查询,今天来讲更新
//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 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 delete(String statement)
    { 
        //委托给update
        return update(statement, null);
    }

    public int delete(String statement, Object parameter)
    {
        return update(statement, parameter);
    }
    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));
        }
    }
    //刷新Statements
    public List flushStatements()
    {
        List list;
        try
        {
            list = executor.flushStatements();
        }
    }
}

从DefaultSqlSession类,看一看出插入,删除,更新操作实际上都是调用update方法,下面
我们来看一下这个方法
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));
        }
    }

update方法委托给具体的executor,executor默认为CachingExecutor,CachingExecutor为执行器代理,具体executor
有SimpleExecutor,BatchExecutor;
下面来看SimpleExecutor
//CachingExecutor
public int update(MappedStatement ms, Object parameterObject)
        throws SQLException
    {
        flushCacheIfRequired(ms);
        return _flddelegate.update(ms, parameterObject);
    }

具体执行器SimpleExecutor
//BaseExecutor
  
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;

//SimpleExecutor
public int doUpdate(MappedStatement ms, Object parameter)
        throws SQLException
    {
        Statement stmt = null;
        int i;
        Configuration configuration = ms.getConfiguration();
	//创建StatementHandler
        StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
        //创建Statement
	stmt = prepareStatement(handler, ms.getStatementLog());
	//执行查询
        i = handler.update(stmt);
	//Statement关闭
        closeStatement(stmt);
    }

//创建StatementHandler,创建Statement,执行查询,Statement关闭,上一篇我们已经说,这里就不说了,
我们看一下BatchExecutor
public class BatchExecutor extends BaseExecutor
{
    public static final int BATCH_UPDATE_RETURN_VALUE = -2147482646;
    private final List statementList = new ArrayList();//statement集合
    private final List batchResultList = new ArrayList();//结果集合
    private String currentSql;
    private MappedStatement currentStatement;
    
    public BatchExecutor(Configuration configuration, Transaction transaction)
    {
        super(configuration, transaction);
    }
     public int doUpdate(MappedStatement ms, Object parameterObject)
        throws SQLException
    {
        Configuration configuration = ms.getConfiguration();
	//创建StatementHandler
        StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null);
        BoundSql boundSql = handler.getBoundSql();
        String sql = boundSql.getSql();
        Statement stmt;
        if(sql.equals(currentSql) && ms.equals(currentStatement))
        {
	   //如果sql与currentSql相等,则从statementList获取Statement
            int last = statementList.size() - 1;
            stmt = (Statement)statementList.get(last);
            BatchResult batchResult = (BatchResult)batchResultList.get(last);
            batchResult.addParameterObject(parameterObject);
        } else
        {
	    //获取连接
            java.sql.Connection connection = getConnection(ms.getStatementLog());
	    //创建statement
            stmt = handler.prepare(connection);
            currentSql = sql;
            currentStatement = ms;
	    //将statement添加到statementList
            statementList.add(stmt);
            batchResultList.add(new BatchResult(ms, sql, parameterObject));
        }
	//设置statement参数
        handler.parameterize(stmt);
	//
        handler.batch(stmt);
        return -2147482646;
    }
}

//执行statement
handler.batch(stmt);

handler为RoutingStatementHandler,RoutingStatementHandler为StatementHandler的代理类,具体可能为SimpleStatementHandler,PreparedStatementHandler,
CallableStatementHandler;
下面我们来看一下RoutingStatementHandler的batch
//RoutingStatementHandler
public class RoutingStatementHandler
    implements StatementHandler
{
 private final StatementHandler _flddelegate;
  public void batch(Statement statement)
        throws SQLException
    {
        _flddelegate.batch(statement);
    }
}

RoutingStatementHandler的batch方法实际上,是调用代理的batch方法,
//PreparedStatementHandler
public class PreparedStatementHandler extends BaseStatementHandler
{
public void batch(Statement statement)
        throws SQLException
    {
        PreparedStatement ps = (PreparedStatement)statement;
        ps.addBatch();
    }
}

//CallableStatementHandler
 
 public void batch(Statement statement)
        throws SQLException
    {
        CallableStatement cs = (CallableStatement)statement;
        cs.addBatch();
    }

具体为调用CallableStatement和PreparedStatement的批处理函数
讲到批处理,我们来看一下 DefaultSqlSession的flushStatements方法
public List flushStatements()
    {
        List list;
        try
        {
            list = executor.flushStatements();
        } 
    }

这里我们来看一下具体executor的flushStatements
//BatchExecutor
public List doFlushStatements(boolean isRollback)
        throws SQLException
    {
        List results;
        List list;
        results = new ArrayList();
        if(!isRollback)
            break MISSING_BLOCK_LABEL_83;
        list = Collections.emptyList();
        Statement stmt;
	//关闭statementList中的Statement
        for(Iterator i$ = statementList.iterator(); i$.hasNext(); closeStatement(stmt))
            stmt = (Statement)i$.next();
        //currentSql,设为null
        currentSql = null;
        statementList.clear();
        batchResultList.clear();
        return list;
    }

BatchExecutor的doFlushStatements主要是关闭statementList中的Statement,
清空statementList与batchResultList
//SimpleExecutor
public List doFlushStatements(boolean isRollback)
        throws SQLException
    {
        return Collections.emptyList();
    }

SimpleExecutor没做任何事情,从上可以看出doFlushStatements,主要是BatchExecutor会用到;
总结:
Sqlsession的update,通过CachingExecutor代理,CachingExecutor是SimpleExecutor,BatchExecutor等执行器代理执行器;CachingExecutor是调用Executor的相应方法。SimpleExecutor,BatchExecutor为实际执行器,继承BatchExecutor。SimpleExecutor更新,构造StatementHandler,获取Statement,执行查询,关闭statement。BatchExecutor的doFlushStatements主要是关闭statementList中的Statement,
清空statementList与batchResultList


猜你喜欢

转载自donald-draper.iteye.com/blog/2339033
今日推荐