DefaultSqlSession第二讲-更新,刷新Statement

本文深入探讨了MyBatis框架中DefaultSqlSession类的更新机制,包括插入、删除、更新操作如何统一委托给update方法处理,以及SimpleExecutor与BatchExecutor两种执行器的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇文章中,我们讲到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会用到;
总结:
[color=blue]Sqlsession的update,通过CachingExecutor代理,CachingExecutor是SimpleExecutor,BatchExecutor等执行器代理执行器;CachingExecutor是调用Executor的相应方法。SimpleExecutor,BatchExecutor为实际执行器,继承BatchExecutor。SimpleExecutor更新,构造StatementHandler,获取Statement,执行查询,关闭statement。BatchExecutor的doFlushStatements主要是关闭statementList中的Statement,
清空statementList与batchResultList[/color]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值