当前位置: 代码迷 >> 综合 >> Mybatis 中 Mapper 接口的存储与实现
  详细解决方案

Mybatis 中 Mapper 接口的存储与实现

热度:28   发布时间:2023-11-24 20:09:58.0

在这里插入图片描述


01、前言

在平常我们写的 SSM 框架中, 定义了 Mapper 接口与 .xml 对应的 SQL 文件, 在 Service 层直接注入 xxxMapper 就可以了

也没有看到像 JDBC 操作数据库的操作, Mybatis 在中间是如何为我们省略下这些重复繁琐的操作呢

这里使用 Mybatis 源码中的测试类进行验证, 首先定义 Mapper 接口, 省事直接注解定义 SQL

AutoConstructorMapper

这里使用 SqlSession 来获取 Mapper 操作数据库, 测试方法如下

primitiveSubjects

02、创建 SqlSession

#1 从 SqlSessionFactory 中打开一个 新的 SqlSession


03、获取 Mapper 实例

#2 就存在一个疑问点, 定义的 AutoConstructorMapper 明明是个接口, 为什么可以实例化为对象?


04、动态代理方法调用

#3 通过创建的对象调用类中具体的方法, 这里具体聊一下 #2 操作

SqlSession 是一个接口, 有一个 默认的实现类 DefaultSqlSession, 类中包含了 Configuration 属性

Mapper 接口的信息以及 .xml 中 SQL 语句是在 Mybatis 初始化时添加 到 Configuration 的 MapperRegistry 属性中的

MapperRegistry#addMapper

#2 中的 getMapper 就是从 MapperRegistry 中获取 Mapper

看一下 MapperRegistry 的类属性都有什么

MapperRegistry

config 为 保持全局唯一 的 Configuration 对象引用

knownMappers 中 Key-Class 是 Mapper 对象, Value-MapperProxyFactory 是通过 Mapper 对象衍生出的 Mapper 代理工厂

再看一下 MapperProxyFactory 类的结构信息

MapperProxyFactory

mapperInterface 属性是 Mapper 对象的引用, methodCache 的 key 是 Mapper 中的方法, value 是 Mapper 解析对应 SQL 产生的 MapperMethod

? Mybatis 设计 methodCache 属性时使用到了 懒加载机制, 在初始化时不会增加对应 Method, 而是在 第一次调用时新增

cachedMapperMethod

05、MapperMethod

MapperMethod 运行时数据如下, 比较容易理解

MapperMethod 运行状态

通过一个实际例子帮忙理解一下 MapperRegistry 类关系, Mapper 初始化第一次调用的对象状态, 可以看到 methodCache 容量为0

MapperRegistry 运行状态

我们目前已经知道 MapperRegistry 的类关系, 回头继续看一下第二步的 MapperRegistry#getMapper() 处理步骤

getMapper

核心处理在 MapperProxyFactory#newInstance() 方法中, 继续跟进

newInstance

MapperProxy 继承了 InvocationHandler 接口, 通过 newInstance() 最终返回的是由 Java Proxy 动态代理返回的动态代理实现类

看到这里就清楚了步骤二中接口为什么能够被实例化, 返回的是 接口的动态代理实现类


微信搜索【源码兴趣圈】,关注龙台,回复【资料】领取涵盖 GO、Netty、SpringCLoud Alibaba、Seata、开发规范、面试宝典、数据结构等电子书 or 视频学习资料!

  相关解决方案