文章插图
RoutingStatementHandler 使用了策略模式 , RoutingStatementHandler 是策略类 , 而 SimpleStatementHandler、PreparedStatementHandler、CallableStatementHandler 则是实现了具体算法的实现类 , RoutingStatementHandler 对象会根据 MappedStatement 对象的 StatementType 属性值选择使用相应的策略去执行 。
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {// RoutingStatementHandler的作用就是根据ms的配置 , 生成一个相对应的StatementHandler对象// 并设置到持有的delegate属性中 , 本对象的所有方法都是通过调用delegate的相应方法实现的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());}}
BaseStaementHandler看它以 Base 开头 , 就可以猜到 它是一个实现了 StatementHandler 接口的抽象类 , 这个类只提供了一些参数绑定相关的方法 , 并没有实现操作数据库的方法 。
BaseStatementHandler 主要实现了 StatementHandler 接口中的 prepare()方法 , BaseStatementHandler 依赖两个重要的组件 , ParameterHandler 和 ResultSetHandler 。
3.ParameterHandlerDefaultParameterHandler默认实现
我们要执行的 SQL 语句中可能包含占位符"?" , 而每个"?"都对应了 BoundSql 中 parameterMappings 集合中的一个元素 , 在该 ParameterMapping 对象中记录了对应的参数名称以及该参数的相关属性 。ParameterHandler 接口定义了一个非常重要的方法 setParameters() , 该方法主要负责调用 PreparedStatement 的 set*()系列方法 , 为 SQL 语句绑定实参 。MyBatis 只为 ParameterHandler 接口提供了唯一一个实现类 DefaultParameterHandler 。
4.ResultSetHandlerSqlSession
文章插图
DefaultSqlSession 是单独使用 MyBatis 进行开发时 , 最常用的 SqISession 接口实现 。其实现了 SqISession 接口中定义的方法 , 及各方法的重载 。select()系列方法、selectOne()系列方法、selectList()系列方法、selectMap()系列方法之间的调用 , 殊途同归 , 它们最终都会调用 Executor 的 query()方法 。
上述重载方法最终都是通过调用 Executor 的 query(MappedStatement, Object, RowBounds,ResultHandler)方法实现数据库查询操作的 , 但各自对结果对象进行了相应的调整 , 例如:selectOne()方法是从结果对象集合中获取了第一个元素返回;selectMap()方法会将 List 类型的结果集 转换成 Map 类型集合返回;select()方法是将结果集交由用户指定的 ResultHandler 对象处理 , 且没有返回值;selectList()方法则是直接返回结果对象集合 。DefaultSqlSession 的 insert()方法、update()方法、delete()方法也有多个重载 , 它们最后都是通过调用 DefaultSqlSession 的 update(String, Object)方法实现的 , 该重载首先会将 dirty 字段置为 true , 然后再通过 Executor 的 update()方法完成数据库修改操作 。DefaultSqlSession 的 commit()方法、rollback()方法以及 close()方法都会调用 Executor 中相应的方法 , 其中就会涉及清空缓存的操作 , 之后就会将 dirty 字段设置为 false 。上述的 dirty 字段主要在
isCommitOrRollbackRequired()方法中 , 与 autoCommit 字段以及用户传入的 force 参数共同决定是否提交/回滚事务 。该方法的返回值将作为 Executor 的 commit()方法和 rollback()方法的参数 。
SqlSessionFactory 负责创建 SqlSession 对象 , 其中包含了多个 openSession()方法的重载 , 可以通过其参数指定事务的隔离级别、底层使用 Executor 的类型、以及是否自动提交事务等方面的配置 。
DefaultSqlSessionFactory 是 SqlSessionFactory 接口的默认实现 , 主要提供了两种创建 DefaultSqlSession 对象的方式 , 一种方式是通过数据源获取数据库连接 , 并创建 Executor 对象以及 DefaultSqlSession 对象;另一种方式是用户提供数据库连接对象 , DefaultSqlSessionFactory 根据该数据库连接对象获取 autoCommit 属性 , 创建 Executor 对象以及 DefaultSqlSession 对象 。
推荐阅读
- 什么是域名泛解析,有什么用途?
- dns解析失败如何处理?
- Spring boot 2.x 集成Mybatis-plus 实现多租户
- 从源码看Log4j2、FastJson漏洞
- 域名解析故障排查的几种常见方法
- JAVA并发之ReentrantLock原理解析
- Log4j漏洞源码分析及解决方案
- 穿衣搭配|五月十二星座运势全面解析 2022.5
- 解析:阳台用什么地砖风水好
- 从Linux源码角度看Epoll,透过现象看本质