MyBatis 的 DAO 接口跟 XML 文件里面的 SQL 是如何建立关系的?( 二 )


MyBatis 的 DAO 接口跟 XML 文件里面的 SQL 是如何建立关系的?文章插图
MyBatis 的 DAO 接口跟 XML 文件里面的 SQL 是如何建立关系的?文章插图
处理的过程相对比较简单 , 只是往 BeanDefinition 对象中设置了一些属性 。 例如:

  • 设置 beanClass
设置 BeanDefinition 对象的 BeanClass 为 MapperFactoryBean。 这就相当于使用 MemberMapper 注册时:当前的 mapper 接口在 Spring 容器中 , beanName 是 memberMapper , beanClass 是 MapperFactoryBean.class 。 故在Spring 的 IOC 初始化的时候 , 实例化的对象就是 MapperFactoryBean 对象 。
  • 设置 sqlSessionFactory 属性
为 BeanDefinition 对象添加属性 sqlSessionFactory , 是为了 BeanDefinition对象设置 PropertyValue 的时候 , 方便调用到 setSqlSessionFactory() 。
MyBatis 的 DAO 接口跟 XML 文件里面的 SQL 是如何建立关系的?文章插图
3.4、创建 sqlSession 代理类
最终在 setSqlSessionFactory 这个方法里 , sqlSession 获取到的是 SqlSessionTemplate 实例 。 而在 SqlSessionTemplate 对象中 , 主要包含sqlSessionFactory 和 sqlSessionProxy , 而 sqlSessionProxy 实际上是 SqlSession 接口的代理对象 。 实际调用的是代理类的 invoke 方法 。
MyBatis 的 DAO 接口跟 XML 文件里面的 SQL 是如何建立关系的?文章插图
3.5、小结
Mapper 接口的代理创建过程大致如下:
  • 1、扫描 mapper 接口基本包路径下的所有对象 , 将其注册为BeanDefinition 对象
  • 2、设置 BeanDefinition 的对象的 beanClass 和 sqlSessionFactory 属性(而其中获取 BeanDefinition 对象的时候 , 调用其工厂方法 getObject , 返回 mapper 接口的代理类)
  • 3、设置 sqlSessionFactory 属性的时候 , 会调用 SqlSessionTemplate 的构造方法 , 创建 SqlSession 接口的代理类
最后我们在 Service 层 , 通过
@Resource private MemberMapper memberDao;注入属性的时候 , 返回的就是代理类 。 执行 memberDao 的方法的时候 , 实际调用的也是代理类的 invoke 方法 。
四、回答最开始的问题MyBatis 在初始化 SqlSessionFactoryBean 的时候 , 找到配置需要扫描的基本包路径去解析里面所有的 XML 文件 。 重点就在如下两个地方:
1、创建 SqlSource
MyBatis 会把每个 SQL 标签封装成 SqlSource 对象 。 然后根据 SQL 语句的不同 , 又分为动态 SQL 和静态 SQL。 其中 , 静态 SQL 包含一段 String 类型的 SQL 语句;而动态 SQL 则是由一个个 SqlNode 组成
MyBatis 的 DAO 接口跟 XML 文件里面的 SQL 是如何建立关系的?文章插图
2、创建 MappedStatement
XML 文件中的每一个 SQL 标签就对应一个 MappedStatement 对象 , 这里面有两个属性很重要 。
  • id
全限定类名+方法名组成的 ID 。
  • sqlSource
当前 SQL 标签对应的 SqlSource 对象 。 创建完 MappedStatement 对象 , 会将它缓存到 Configuration#mappedStatements 中 。
前面初始化中提到的 Configuration 对象 , 我们知道它就是 MyBatis 中的配置大管家 , 基本所有的配置信息都维护在这里 。
例如下面这样一段代码:
MyBatis 的 DAO 接口跟 XML 文件里面的 SQL 是如何建立关系的?文章插图
把所有的 XML 都解析完成之后 , Configuration 就包含了所有的 SQL 信息 。 然后解析完成的 XML 大概就是这样了:
MyBatis 的 DAO 接口跟 XML 文件里面的 SQL 是如何建立关系的?文章插图
【MyBatis 的 DAO 接口跟 XML 文件里面的 SQL 是如何建立关系的?】看到上面的图示 , 聪明如你 , 也许就大概知道了 。 当我们执行 MyBatis 方法的时候 , 就通过全限定类名+方法名找到 MappedStatement 对象 , 然后解析里面的 SQL 内容 , 执行即可 。