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 今天遇到一个 ...
随机推荐
- Mac osx 启用和关闭root用户
设置->群组和用户->点击小
- 2018.12.31 NOIP训练 czy的后宫5(树形dp)
传送门 题意:给一棵有根树,树有点权,最多选出mmm个点,如果要选一个点必须先选其祖先,问选出来的点权和最大值是多少. 直接背包转移就行了. 代码
- hdu-1043(八数码+bfs打表+康托展开)
参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...
- NETCLR via C#第四版(文摘)
第1部分 CLR基础 第1章 CLR的执行模型 第2章 生成,打包,部署和管理应用程序及类型 第3章 共享程序集和强命名程序集 第2部分 设计类型 第4章 类型 第5章 基元类型 引用类型和值类型 第 ...
- 菜品识别 SDK调用
from aip import AipImageClassify import os """ 填入参数 """ APP_ID = 'your ...
- shell 常见面试
1.求100以内的质数 #!/bin/bash n= ;i<=n;i++)) do ;x<=i;x++)) do b=$(( $i%$x )) ]]; then a=$a+ fi done ...
- MySQL处理表字段小技巧
MySQL利用正则函数替换值 update dateTest set date=REPLACE(date,'/','') where date REGEXP '\/'; SQL语句讲解: -- 将 所 ...
- VSCode 设置侧边栏字体大小;Visual Studio Code改变侧边栏大小
1.代码改写,进入默认安装的如下路径 C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\resources\app\out ...
- Mybatis-Plus 实战完整学习笔记(七)------select测试二
1.查询selectOne (3.0.3版) @Test public void selectMethod() throws SQLException { // 根据ID获取一个对象的数据 Empl ...
- ajax 简单实例
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script> ...