JDBC中的执行器
jdbc有三种执行器分别是Statement,PreparedStatement,CallableStatement(简单执行器,预先执行器,存储过程执行器)
声明:基本功能:执行静态SQL
PreparedStatement:设置预编译,防止SQL注入
CallableStatement:设置出参,读取参数(用于执行存储过程)
Mybatis执行过程:
主要的执行模块是:SqlSession-> Executor-> StatementHandler->数据库
SqlSession:
SqlSession采用了门面模式方便来让我们使用。他不能跨线程使用。一级缓存生命周期和它一致
基本功能:CRUD辅助功能:提交,关闭会话
执行者
基本功能:改,查,维护缓存 辅助功能:提交,关闭执行器,批处理刷新
声明处理程序
经过执行器处理后交给了StatementHandler(声明处理器)
主要作用就是:参数处理,结果处理
Mybatis执行器:
Mybatis给我们提供了一个执行器,分别是SimpleExecutor,ResuseExecutor,BathExecutor(分别是简单执行器,可重用执行器,批处理执行器)不配置或就是简单执行器。
(这三个执行器继承了一个BaseExecutor(基础执行器),而这个基础执行器实现了Executor接口)
其实还有一种执行器CachingExecutor(二级缓存执行器)你打开二级缓存并通过实例化它。它采用的是装饰器模式它里面有个属性是Executor委托;(实例化其中自己配置的,替代是SimpleExecutor,使用有参构造给属性赋值)这里存的就是你三种执行器中的一种。
下面的这个方法是实例化SqlSession的时候产生的执行器。使用的时候会判断你有没有缓存,没有则去使用delegate中的执行器。。。
//产生执行器(该方法在创建SqlSession做的事情)
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
//防止将defaultExecutorType设成null
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
//然后就是简单的3个分支,产生3种执行器BatchExecutor/ReuseExecutor/SimpleExecutor
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);
}
//如果要求缓存,实例化CachingExecutor(默认就是有缓存),装饰者模式
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
//此处调用插件,通过插件可以改变Executor行为(查看插件文章)
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
简单执行器
每次都会创建一个新的预器(PrepareStatement)每次执行的SQL都会进行一次预编译。
重用执行器
只要是相同的SQL只会进行一次初步
键是我们的SQL语句,值是我们的Statement对象
原理:
//可重用的执行器内部用了一个map,用来缓存SQL语句对应的Statement对象
private final Map<String, Statement> statementMap = new HashMap<String, Statement>();
BatchExecutor
批处理只对增删改改SQL有效
执行sql需要满足三个条件才能使用同一个Statement(使用同一个Statement是为了压缩体积,减少SQL预处理)
================
1.sql相同
2.同一个MappedStatement(sql标签的配置都在这里面)
3.执行的顺序必须是连续的
=================
下面就是BatchExecutor里面的doUpdate方法。代码上可以修剪上一个添加的是否是这个sql(currentSql)并且是同一个MappedStatement currentStatement(映射语句)【if(sql.equals(currentSql)&& ms.equals(currentStatement) )】;
属性是(parameterObject)【batchResult.addParameterObject(parameterObject);】;满足条件就将参数放到当前这个BatchResult对象中的参数。
不满足条件则获取一个Statement实例再实例化BatchResult对象。最后放到列表中去,再给current和MappedStatement currentStatement赋值
批处理提交必须执行flushStatements才会生效(合并一个个的Statement提交)可以减少与数据库交互次数
public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException {
final Configuration configuration = ms.getConfiguration();
final StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null);
final BoundSql boundSql = handler.getBoundSql();
final String sql = boundSql.getSql();
final Statement stmt;
if (sql.equals(currentSql) && ms.equals(currentStatement)) {
int last = statementList.size() - 1;
stmt = statementList.get(last);
BatchResult batchResult = batchResultList.get(last);
batchResult.addParameterObject(parameterObject);
} else {
Connection connection = getConnection(ms.getStatementLog());
stmt = handler.prepare(connection);
currentSql = sql;
currentStatement = ms;
statementList.add(stmt);
batchResultList.add(new BatchResult(ms, sql, parameterObject));
}
handler.parameterize(stmt);
handler.batch(stmt);
return BATCH_UPDATE_RETURN_VALUE;
}
缓存执行器
维护二级缓存,只有在提交事务之后二级缓存才会保存(查询的时候先走二级缓存再走一级缓存【开启二级缓存的条件下】)
//默认是true protected boolean cacheEnabled = true; //mapper.xml 例: 基本执行器基础执行器:维护一级缓存,是简单,重用,批处理这三个执行器的父类。主要逻辑是维护缓存,其他实现交给子类
执行器这个接口有什么方法?
update、query、commit、rollback
//刷新批处理语句
List flushStatements()
//创建CacheKey
CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);
//判断是否缓存了
boolean isCached(MappedStatement ms, CacheKey key);
//清理Session缓存
void clearLocalCache();
//延迟加载
void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);
Transaction getTransaction();
void close(boolean forceRollback);
boolean isClosed();
void setExecutorWrapper(Executor executor);
基本功能:改,查,维护缓存 辅助功能:提交,关闭执行器,批处理刷新