mybatis四大接口之 StatementHandler
1. 继承结构
- StatementHandler:顶层接口
- BaseStatementHandler : 实现顶层接口的抽象类,实现了部分接口,并定义了一个抽象方法
- SimpleStatementHandler:对应JDBC中常用的Statement接口,用于简单SQL的处理;
- PreparedStatementHandler:对应JDBC中的PreparedStatement,预编译SQL的接口;
- CallableStatementHandler:对应JDBC中CallableStatement,用于执行存储过程相关的接口;
- RoutingStatementHandler:这个接口是以上三个接口的路由,没有实际操作,只是负责上面三个StatementHandler的创建及调用。
2. BaseStatementHandler
三个子类都 继承 prepare() 方法,并没有重写该方法。该方法中调用了方法 instantiateStatement ();
instantiateStatement 是一个抽象方法,根据一个Connection 返回一个Statement 对象;
三个子类都实现了该方法,分别返回了 Statement,PrepareStaement 和 CallableStatement 对象。
@Override
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
ErrorContext.instance().sql(boundSql.getSql());
Statement statement = null;
try {
statement = instantiateStatement(connection);
setStatementTimeout(statement, transactionTimeout);
setFetchSize(statement);
return statement;
} catch (SQLException e) {
closeStatement(statement);
throw e;
} catch (Exception e) {
closeStatement(statement);
throw new ExecutorException("Error preparing statement. Cause: " + e, e);
}
} protected abstract Statement instantiateStatement(Connection connection) throws SQLException;
3. 抽象类的子类实现的接口方法
三个子类都实现了 update() ,batch() ,query()。
在对应的方法中将传入的 Statement 对象转型为 具体的 Statement 类型进行相应的操作。
以 PrepareStatement 示例:
@Override
public int update(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
int rows = ps.getUpdateCount();
Object parameterObject = boundSql.getParameterObject();
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
return rows;
} @Override
public void batch(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.addBatch();
} @Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.<E> handleResultSets(ps);
}
4. RoutingStatementHandler
该类采用了代理模式(静态代理);
该类直接实现了 StatmentHandler 接口,实现了接口的全部方法。
该类持有一个 StatmentHandler 的实例,并在创建该类时根据传入的 MappedStatement 的 type 创建不同的 Statement 实例,然后通过这个具体的实例去实现相应的操作。
public class RoutingStatementHandler implements StatementHandler { private final StatementHandler delegate; public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { switch (ms.getStatementType()) {
case STATEMENT:
delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case PREPARED:
delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case CALLABLE:
delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
default:
throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
} } @Override
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
return delegate.prepare(connection, transactionTimeout);
} @Override
public void parameterize(Statement statement) throws SQLException {
delegate.parameterize(statement);
} @Override
public void batch(Statement statement) throws SQLException {
delegate.batch(statement);
} // 其他方法同理
...
}
mybatis四大接口之 StatementHandler的更多相关文章
- mybatis四大接口之 Executor
[参考文章]:Mybatis-Executor解析 1. Executor的继承结构 2. Executor(顶层接口) 定义了执行器的一些基本操作: public interface Executo ...
- mybatis四大接口之 ResultSetHandler
1. 继承结构 2. ResultSetHandler public interface ResultSetHandler { // 将Statement执行后产生的结果集(可能有多个结果集)映射为结 ...
- mybatis四大接口之 ParameterHandler
1. 继承结构 只有一个默认的实现类 2. ParameterHandler 获取参数对象: 设置参数对象: public interface ParameterHandler { Object g ...
- Java集合框架之四大接口、常用实现类
Java集合框架 <Java集合框架的四大接口> Collection:存储无序的.不唯一的数据:其下有List和Set两大接口. List:存储有序的.不唯一的数据: Set:存储无序的 ...
- Mybatis中接口和对应的mapper文件命名为什么需要一样?
背景: 自己对于Mybatis现阶段只处于会用的阶段,有些问题,自己还是想深入的了解一下.就拿Mybatis的接口文件和mapper文件命名需要一致来开始. 解决: 当我们将接口和mapper文件放在 ...
- Mybatis Mapper接口是如何找到实现类的-源码分析
KeyWords: Mybatis 原理,源码,Mybatis Mapper 接口实现类,代理模式,动态代理,Java动态代理,Proxy.newProxyInstance,Mapper 映射,Map ...
- Mybatis中接口和对应的mapper文件位置配置深入剖析
首先要说明的问题是,Mybatis中接口和对应的mapper文件不一定要放在同一个包下,放在一起的目的是为了Mybatis进行自动扫描,并且要注意此时java接口的名称和mapper文件的名称要相同, ...
- 基于注解的Mybatis mapper 接口注意事项
基于注解的Mybatis mapper 接口功能没有mapper xml配置文件丰富,并且动态sql语句的灵活性不能和xml配置相比. 这里仅仅说一下基于注解的动态sql注意事项: Mybatis提供 ...
- Mybatis中接口和对应的mapper文件位置配置详解
Mybatis中接口和对应的mapper文件位置配置详解 原链接为:https://blog.csdn.net/fanfanzk1314/article/details/71480954 今天遇到一个 ...
随机推荐
- rails 表单中默认值
在表单中加入默认提示值,如(email@email.com): <div class="field"> <%= form.label :email,"E ...
- 2018.11.24 poj3693Maximum repetition substring(后缀数组)
传送门 后缀数组好题. 考虑枚举循环节长度lenlenlen. 然后考虑枚举循环节的起点来更新答案. 但是直接枚举每次O(n)O(n)O(n). 考虑枚举len∗k+1len*k+1len∗k+1作为 ...
- RNN文章总结
1.RNN 基本结构类型 2. RNN 3.零基础入门深度学习(5) - 循环神经网络 4.
- C# 编码标准(二)
先八卦一下,昨天写了C# 编码标准(一),得到了@h82258652的补充,感到非常欣慰,一是感觉他的观点扩展了我的视野,丰富了我的看法,所以更坚定了我继续写博客的想法,由于是五笔打字,经常不写东西, ...
- mouseover和mouseout事件的相关元素
在发生mouseover和mouseout事件时,还会涉及更多的元素,这两个事件都会涉及把鼠标指针从一个元素的边界之内移动到另一个元素的边界之内.对mouseover事件而言,事件的主目标获得光标元素 ...
- 腾讯云 centos 一键安装nginx环境
这里测试centos版本为7.4 进入命令行直接敲入一下代码 $ yum install nginx 根据提示 进行确认 下一步 即可安装完毕: 服务器默认根目录为 : /usr/share/ngin ...
- 同时安装python2.7和python3.5
同时安装python2.7和python3.5,并配置sublime ctrl+B选择运行python版本 安装python 首先是安装两个版本的python,并配置相应的环境变量 1.在下载安装好P ...
- 分区表主键不包含分区键报错ERROR 1105 (HY000)
ERROR 1105 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function MySQ ...
- java调用执行cmd指令启动weblogic
这里的例子是启动weblogic import java.io.BufferedReader; import java.io.IOException; import java.io.InputStre ...
- Warning:The /usr/local/mysql/data directory is not owned by the 'mysql' or '_mysql'
Mac OS X的升级或其他原因可能会导致MySQL启动或开机自动运行时 在MySQL操作面板上会提示“Warning:The /usr/local/mysql/data directory is ...