上一篇文章中,我们讲到DefaultSqlSession的查询,今天来讲更新
//DefaultSqlSession
从DefaultSqlSession类,看一看出插入,删除,更新操作实际上都是调用update方法,下面
我们来看一下这个方法
update方法委托给具体的executor,executor默认为CachingExecutor,CachingExecutor为执行器代理,具体executor
有SimpleExecutor,BatchExecutor;
下面来看SimpleExecutor
//CachingExecutor
具体执行器SimpleExecutor
//BaseExecutor
//SimpleExecutor
//创建StatementHandler,创建Statement,执行查询,Statement关闭,上一篇我们已经说,这里就不说了,
我们看一下BatchExecutor
//执行statement
handler为RoutingStatementHandler,RoutingStatementHandler为StatementHandler的代理类,具体可能为SimpleStatementHandler,PreparedStatementHandler,
CallableStatementHandler;
下面我们来看一下RoutingStatementHandler的batch
//RoutingStatementHandler
RoutingStatementHandler的batch方法实际上,是调用代理的batch方法,
//PreparedStatementHandler
//CallableStatementHandler
具体为调用CallableStatement和PreparedStatement的批处理函数
讲到批处理,我们来看一下 DefaultSqlSession的flushStatements方法
这里我们来看一下具体executor的flushStatements
//BatchExecutor
BatchExecutor的doFlushStatements主要是关闭statementList中的Statement,
清空statementList与batchResultList
//SimpleExecutor
SimpleExecutor没做任何事情,从上可以看出doFlushStatements,主要是BatchExecutor会用到;
总结:
[color=blue]Sqlsession的update,通过CachingExecutor代理,CachingExecutor是SimpleExecutor,BatchExecutor等执行器代理执行器;CachingExecutor是调用Executor的相应方法。SimpleExecutor,BatchExecutor为实际执行器,继承BatchExecutor。SimpleExecutor更新,构造StatementHandler,获取Statement,执行查询,关闭statement。BatchExecutor的doFlushStatements主要是关闭statementList中的Statement,
清空statementList与batchResultList[/color]
//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会用到;
总结:
[color=blue]Sqlsession的update,通过CachingExecutor代理,CachingExecutor是SimpleExecutor,BatchExecutor等执行器代理执行器;CachingExecutor是调用Executor的相应方法。SimpleExecutor,BatchExecutor为实际执行器,继承BatchExecutor。SimpleExecutor更新,构造StatementHandler,获取Statement,执行查询,关闭statement。BatchExecutor的doFlushStatements主要是关闭statementList中的Statement,
清空statementList与batchResultList[/color]