示例代码
InputStream inputStream = new FileInputStream(new File("src/main/resources/mybatis-config.xml"));
// 1.加载配置文件创建configuration对象,创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2.创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取Mapper接口动态代理
BaseTermMapper mapper = sqlSession.getMapper(BaseTermMapper.class);
// 4.动态代理回调sqlSession中的查询方法,sqlSession将查询方法转发给Executor,
// Executor基于JDBC访问数据库获取数据并通过反射将数据转换成POJO并返回
BaseTerm baseTerm = mapper.selectById(1);
System.out.println(baseTerm.getName());
sqlSession.close();
sqlSessionFactory.openSession()的流程在mybatis数据源模块分析中有具体分析。
这里主要分析获取Mapper接口动态代理的流程
binding的核心类主要有:
MapperRegistry : mapper接口和对应的代理对象工厂的注册中心;
MapperProxyFactory:用于生成mapper接口动态代理的实例对象;
MapperProxy:实现了InvocationHandler接口,它是增强mapper接口的实现;
MapperMethod:封装了Mapper接口中对应方法的信息,以及对应的sql语句的信息;它是mapper接口与映射配置文件中sql语句的桥梁;
现在开始进入源码流程
// 3.获取Mapper接口动态代理
BaseTermMapper mapper = sqlSession.getMapper(BaseTermMapper.class);
这里就可以看出BaseTermMapper mapper = sqlSession.getMapper(BaseTermMapper.class); 返回的mapper其实是MapperProxy动态代理类。
接下来看调用查询方法的时候源码是如何实现的。
因为此时的mapper是MapperProxy动态代理类,mapper.selectById(1)方法会调用到MapperProxy的invoke方法
MapperMethod的部分源码如下:
可以看到调用的是sqlSession.selectOne方法
此时具体对象内容如下:
可以看到最后sqlSession并没有正在处理sql请求,而是转交给executor去查询数据库并将数据映射封装返回。至此第二阶段Mapper的binding流程结束。
以下是Mapper代理类的简单原理代码:
最后调用代码: