DefaultSqlSession第二讲-更新,刷新Statement 博客分类: Mybatis MybatisDefaultSqlSession
程序员文章站
2024-02-12 23:42:58
...
上一篇文章中,我们讲到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会用到;
总结:
Sqlsession的update,通过CachingExecutor代理,CachingExecutor是SimpleExecutor,BatchExecutor等执行器代理执行器;CachingExecutor是调用Executor的相应方法。SimpleExecutor,BatchExecutor为实际执行器,继承BatchExecutor。SimpleExecutor更新,构造StatementHandler,获取Statement,执行查询,关闭statement。BatchExecutor的doFlushStatements主要是关闭statementList中的Statement,
清空statementList与batchResultList
//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