Mapper解析

你有没有好奇过,使用Mybatis时,为什么我们只需定义接口及xml文件即可完成数据库操作?今天这篇文章就带大家一起来探索一下这个过程,我将从Mapper的解析、调用两方面进行叙述,发车~~~

一、Mapper解析

Mapper解析时主要完成两个任务,一是将Mapper注册至Mapper映射表mapperRegistry中,二是将注解sql、XML sql解析为mappedStatements。

因为mybatis在配置mapper扫描时有不同的方式,所以在完成Mapper的解析时也有所不同,但本质上还是不变的。

当按包路径、类路径进行扫描时,解析Mapper配置内容的统一入口为MapperAnnotationBuilder,而按resource、url进行扫描时,解析Mapper配置内容的统一入口则为XMLMapperBuilder。

以下为不同情况的Mapper配置内容解析调用链。

1、按包路径、类路径进行扫描

一旦 Mapper 注册完成,就由 MapperAnnotationBuilder.parse() 接管:既能解析接口上的注解SQL,也能在命名空间一致时加载并解析 XML,二者在底层通过 LanguageDriver 统一收敛为 SqlSource 。

2、按resource、url进行扫描

可以看出,上述两种场景下解析sql内容,前者的入口为MapperAnnotationBuilder,在解析过程中会调用XMLMapperBuilder,而后者则直接调用XMLMapperBuilder进行解析。那这么做是为什么呢?

  • 扫描 package 时,入口是接口而不是 XML 文件。系统只"知道一堆接口",所以必须以接口为主导,用 MapperAnnotationBuilder 做"总协调":既解析方法注解,也"按约定"去找同名 XML 并调用 XMLMapperBuilder 解析。也就是说,MapperAnnotationBuilder 既负责解析注解,又以约定方式"发现并解析"同名 XML,最终把所有 SQL 收敛到 MappedStatement 。
  • 扫描 resource 时,入口就是一个已知的 XML 文件。既然资源已经明确,直接构造 XMLMapperBuilder 读取并解析 XML,完全不需要经过接口协调器。也就是说,XMLMapperBuilder 直接解析 XML 中的 SQL,必要时把命名空间绑定到接口,保证执行期代理与语句能对上号。

这下,我们就知道了,当只提供"接口所在包"时,框架需要一个"总协调器"从接口视角整合注解与 XML;而当明确给了"XML 文件路径"时,框架就可以直奔主题进入 XML 解析器。这是 MyBatis 为兼容"注解 Mapper + XML Mapper + 接口配套 XML"三种使用姿势而做出的清晰职责划分。

二、Mapper调用

1、调用时序图

2、组件关系图

三、深度思考

1、接口和 SQL(XML / 注解)如何关联?

MyBatis 在初始化阶段通过以下两种方式完成绑定:

(1) XML 与接口关联:

通过 @MapperScan 注解扫描指定包下的 Mapper 接口,同时读取配置的 XML 文件路径(如 mybatis.mapper-locations=classpath:mapper/*.xml),将 XML 中 namespace(接口全限定名)与接口匹配,id(方法名)与接口方法匹配;

(2) 注解与接口关联:

扫描接口时直接解析方法上的 @Select/@Insert 等注解,无需 XML 文件,SQL 通过注解直接与方法绑定,无需额外的 namespace 配置。

2、Mapper 接口能不能进行方法重载?

不能。

原因是 MyBatis 通过 "方法名" 作为核心标识匹配 SQL(XML 中的 id 或注解绑定的方法),若存在重载方法(方法名相同、参数不同),会导致 SQL 标识冲突,MyBatis 无法区分对应的 SQL,启动时会抛出异常(如 BindingException: Invalid bound statement)。

相关推荐
寻星探路1 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
曹牧4 小时前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
爬山算法4 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty7254 小时前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎5 小时前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
李少兄5 小时前
在 IntelliJ IDEA 中修改 Git 远程仓库地址
java·git·intellij-idea
忆~遂愿5 小时前
ops-cv 算子库深度解析:面向视觉任务的硬件优化与数据布局(NCHW/NHWC)策略
java·大数据·linux·人工智能
小韩学长yyds5 小时前
Java序列化避坑指南:明确这4种场景,再也不盲目实现Serializable
java·序列化
仟濹5 小时前
【Java基础】多态 | 打卡day2
java·开发语言
Re.不晚5 小时前
JAVA进阶之路——无奖问答挑战2
java·开发语言