系列内容回顾:
前面的文章分析了Mybatis是如何在给定接口的情况下, 代替我们生成代理对象的, 这篇文章接着带大家来学习Mybatis.
在之前提到, 无论是用代理生成Dao类还是自己手写Dao类, 都是用工厂方法获得一个SqlSession
, 然后调用其select
, update
, insert
方法; 我们也知道, 如果用最原始的JDBC的方法来写, 通常落到执行层面, 通常就是pstmt.executeUpdate
, pstmt.executeQuery
, pstmt.execute
, stmt.execute
这样的一些方法. 那么Mybatis
中是如何代替我们用SqlSession
的方法去操纵底层JDBC的, 这就是今天想分析的内容.
SqlSession
SqlSession
是Mybatis中非常重要的接口, 通过定义了对数据库的常见操作的方法, 屏蔽了底层jdbc细节, 我们先看下该接口提供的方法都有哪些.
可以看到, 除了commit, rollback这样的事务相关的方法, 大多数方法支持的是各种模式的CRUD. 我们可以将他们分为两个部分, 一个是select相关的, 一个是update相关的(update/delete/insert), 通过阅读源码可以发现后者中的方法最终都是对update(String statement, Object parameter)
这样一个方法进行的封装; 而前者中提供的各种方法是对
select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler)
selectCursor(String statement, Object parameter, RowBounds rowBounds)
selectList(String statement, Object parameter, RowBounds rowBounds)
进行的封装. 因此接下来的重点就是上述的四个方法.
executor.update
update(String statement, Object parameter)
方法的底层调用的是executor.update(MappedStatement ms, Object parameter)
方法, executor 则是SqlSession中执行数据库操作的实际对象, 通过跟踪代码, 可以看到, executor是个一个接口, 里面封装了query和update两种sql statement的执行模型, 这个接口有的接口大致如下:
在SqlSession中, 实际实际引入的executor的实现类是CachingExecutor
, 但是注意到CachingExecutor
本身是一个装饰器模式, 用来处理和查询缓存相关的工作, 其真正功能由成员Executor delegate
完成, delegate是一个SimpleExecutor
的实例, 这个类的结构很简单
/**
* @author Clinton Begin
*/
public class SimpleExecutor extends BaseExecutor {
public SimpleExecutor(Configuration configuration, Transaction transaction) {
}
@Override
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
}
@Override
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException