在SqlSessionTest里面有这样一个测试类:
//前置操作
@BeforeAll
static void setup() throws Exception {
createBlogDataSource();
final String resource = "org/apache/ibatis/builder/MapperConfig.xml";
final Reader reader = Resources.getResourceAsReader(resource);
//構建sqlMapper:首先创建xml配置构建对象,也即xmlConfigBuilder,然后进行构建,而构建的重点是执行解析
//xml配置构建,执行xpath解析,此时首先创建xpath解析对象,而这个时候会创建XPathParser
//执行解析操作,如果已经解析,则抛异常,否者将解析设置为true,同时执行evalNode操作将配置解析成XNode,然后解析配置
//返回xnode对象,然后将拿到的节点进行返回
sqlMapper = new SqlSessionFactoryBuilder().build(reader);
}
//执行获取sqlSesson,然后获取mapper,最后执行查询
@Test
void shouldSelectAuthorsUsingMapperClass() {
//打开session,打开session从数据源中,通过configuration获取environment,通过环境获取事务工厂
//通过事务工厂创建新事务,通过配置获取新执行器,返回新的默认sqlSession
//创建新事务是jdbc事务,里面包含数据源、隔离级别、是否自动提交
// 创建新执行器,执行类型:如果为空,则简单,判断执行类型:批量、重用、简单,
// 如果缓存设置为true,则创建新的缓存执行器,放入configuration、executor、是否提交到defaultSqlSession,返回新的默认sqlSession
//其中:baseExecutor基本执行器:事务、递延加载、本地缓存、本地输出参数缓存、关闭、配置、包装
try (SqlSession session = sqlMapper.openSession()) {
//获取mapper
AuthorMapper mapper = session.getMapper(AuthorMapper.class);
//执行sql查询,经过动态代理,其会执行缓存查询CachingExecutor和simpleExecutor
List<Author> authors = mapper.selectAllAuthors();
assertEquals(2, authors.size());
}
}
那么它的流程又是怎样的呢?
其中最为重要的是执行的过程中,对sqlSession的构建、sqlSession的开启,以及通过sqlSession拿到mapper,然后执行sql查询的过程。对应sqlSession的构建是通过xpath来完成的,首先获取xpath解析的xmlConfigBuilder,而其本质是xpath,然后执行解析操作,而解析操作包含两个:解析节点为XNode和解析配置这个步骤。
解析完成的配置都会放入到configuration中,然后执行openSession操作,而执行openSession的操作会创建事务和新的执行器,然后将其放入到默认SqlSession,也即DefaultSqlSession中。
然后将拿到的sqlSession进一步拿到mapper,也即getMapper,此时会通过动态代理拿到mapper对象,也即xml中的,此时会借助MapperProxy,通过MapperProxyFacotry可以拿到MapperProxy代理对象。其首先会通过configuration去获取mapper,而其又通过MapperRegistry.getMapper获取mapper,而其又是通过MapperProxyFactory拿到的。因此可以其使用了动态代理。因此可以看到代理过程是在MapperProxy中的invoke中实现的,因此可以看到MapperProxy.invoke方法,进而追踪到mapperMethod.execute(sqlSession, args),找到我们需要找的这个方法执行sql查询操作。而此时首先会执行baseExecutor,如果缓存中有,则直接返回,如果没有,则执行SimpleExecutor中的查询操作,执行doQuery操作。这个过程中涉及到executor.query->delegate.query,直至doQuery,而在doQuery中,我们可以看到这些方法最终会调用原生jdbc的操作,完成最终的查询操作。
下面是它的执行流程:
mybatis执行流程图