在了解MyBatis的运行流程前,先快速了解下MyBatis的四大核心组件,MyBatis的整个执行流程都是围绕这四个组件进行的。
- SqlSessionFactoryBuilder(构造器),会根据配置信息或者代码来生成SqlSessionFactory(工厂接口)
- SqlSessionFactory,用来生成SqlSession(会话)
- SqlSession,是一个既可以发送SQL去执行并返回结果,也可以获取Mapper的接口
- SQL Mapper,由一个Java接口和XML文件(或注解)构成的,需要给出对应的SQL和映射规则,它负责发送SQL去执行,并返回结果
MyBatis的运行分为两部分
- 第一部分是读取配置文件缓存到Configuration对象,用来创建SqlSessionFactory
- 第二部分是SqlSession的执行过程
下面将详细分析这两部分
构建SqlSessionFactory
- 通过XMLConfigBuilder(org.apache.ibatis.builder.xml)解析配置的XML文件,读出配置参数,并将读取的数据存入Configuration(org.apache.ibatis.session)对象中。
- 使用Configuration对象去创建SqlSessionFactory,SqlSessionFactory是一个接口,MyBatis提供了一个默认实现类DefaultSqlSessionFactory(org.apache.ibatis.session.defaults),大部分场景下都不需自己创建SqlSessionFactory实现类
SQLSession运行过程
构建SqlSessionFactory就可以拿到SqlSession,SqlSession提供了增、删、查、改方法,在旧版本的MyBatis或iBatis中基本是直接使用这些方法,在新版本中则是建议使用Mapper,其中Mapper映射是通过动态代理来实现的
SqlSession的四大对象
Mapper映射器通过动态代理对象进入到MapperMethed的execute方法,经过简单判断就可以进入增、删、查、改等方法,然后Mapper的执行过程是通过Executor、StatementHandler、ParameterHandler和ResultHandler来完成数据库操作和结果返回。
Executor
代表执行器,由它来调度StatementHandler、ParameterHandler、ResultHandler等来执行对应的SQL,是一个真正执行Java和数据库交互的东西,有三种执行器,可以通过setting元素中的defaultExecutorType来配置
1. SIMPLE,简易执行器,也是默认的执行器
2. REUSE,重用预处理语句
3. BATCH,执行重用语句和批量更新,是针对批量专用的执行器
StatementHandler
使用数据库的Statement(PrepardStatement)执行操作,它是四大对象的核心,起承上启下的作用,StatementHandler是专门处理数据库会话,Configuration生成StatementHandler会话器的逻辑如下
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
return statementHandler;
}
其中RoutingStatementHandler是StatementHandler的一个具体实现,但不是我们使用的真实对象,它是通过适配模式找到对应的StatementHandler来执行的,主要分为三种
1. SimpleStatementHandler直接使用普通的Statement对象,这样每次执行SQL语句都需要数据库对SQL进行预编译
2. PreparedStatementHandler使用PrepareStatement执行,虽然初次创建PrepareStatement时开销比较大,但在多次处理SQL时只需要初始化一次,可以有效提高性能
3. CallableStatementHandler使用CallableStatement执行,CallableStatement是用来执行存储过程的
各模式执行查询的流程类似,都是实现三个主要方法prepare、parameterize和query
ParameterHandler
用于SQL对参数的处理ParameterHandler(org.apache.ibatis.executor.parameter)的接口定义如下
public interface ParameterHandler {
Object getParameterObject();
void setParameters(PreparedStatement ps)
throws SQLException;
}
默认提供了DefaultParameterHandler实现类
1. getParameterObject返回参数对象
2. setParameters设置预编译SQL语句的参数,主要是从parameterObject对象中取参数,然后使用typeHandler进行参数处理,typeHandler是注册在Configuration里
ResultHandler
是进行最后数据集(ResultSet)的封装返回处理,ResultSetHandler(org.apache.ibatis.executor.resultset)的接口定义如下
public interface ResultSetHandler {
<E> List<E> handleResultSets(Statement stmt) throws SQLException;
<E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException;
void handleOutputParameters(CallableStatement cs) throws SQLException;
}
默认提供了一个实现类DefaultResultSetHandler,实现比较复杂,会涉及Javassist或者CGLIB作为延迟加载,然后通过typeHandler和ObjectFactory进行组装结果再返回。
1. handleOutputParameters是处理存储过程输出参数的
2. handleResultSets是封装结果集的
3. handleCursorResultSets是封装批处理结果集
SqlSession运行流程图如下

SqlSession是通过Executor创建StatementHandler来运行的,而StatementHandler要经过下面三步:
- prepared预编译SQL
- parameterize设置参数
- query/update执行SQL
其中parameterize是调用parameterHandler的方法去设置的,而参数是根据类型处理器typeHandler去处理的,query/update方法是通过ResultHandler进行处理结果的封装,如果是update语句,就返回整数,否则通过typeHandler处理结果类型,然后用ObjectFactory提供的规则组装对象,返回给调用者。这就是SqlSession的主要执行过程
网友评论