当前位置: 首页 > article >正文

【MyBatis 源码阅读与笔记】Mapper 接口的动态代理实现

MyBatis 源码阅读与笔记

题目:Mapper 接口的动态代理实现

  • 研究 MyBatis 如何通过动态代理为 Mapper 接口创建实现类。
  • 重点分析 MapperProxy 类,理解其如何拦截方法调用并执行 SQL。

笔记

1 动态代理原理

MyBatis 使用 JDK 动态代理为 Mapper 接口创建代理类。当调用 Mapper 接口的方法时,实际上是进入 MapperProxy 类的 invoke 方法,执行 SQL 操作。

2 核心类与方法介绍
  • MapperProxy:核心类,负责拦截接口方法调用并执行 SQL。
  • MapperProxyFactory:创建 MapperProxy 的工厂。
  • MapperMethod:封装接口方法与 SQL 之间的映射关系。
  • SqlSession:MyBatis 的核心接口,负责 SQL 执行与事务管理。

3 源码结构分析
3.1 MapperProxy

MapperProxy 是 MyBatis 动态代理的核心类,负责拦截 Mapper 接口的方法调用并执行 SQL。

关键逻辑:

  • invoke():拦截方法调用,判断是否是 Object 类方法,若是则直接执行,不进入 SQL 执行流程。
  • 方法缓存:使用 methodCache 缓存 MapperMethod,避免重复创建。
  • SQL 执行:调用 MapperMethod.execute() 执行 SQL 语句,结果通过 SqlSession 返回。
3.2 MapperMethod

MapperMethod 负责管理接口方法和 SQL 语句的映射关系,封装了执行 SQL 的具体细节。

关键逻辑:

  • execute():根据方法的返回类型,调用相应的 SqlSession 方法(如 selectOneinsert)。
  • SqlCommand:封装 SQL 的基础信息,如 SQL 类型、ID 等。
  • MethodSignature:确保方法签名(如返回类型和参数)一致,保证数据的正确性。
3.3 MapperProxyFactory

MapperProxyFactory 用于创建 MapperProxy 实例,生成具体的代理对象。

关键逻辑:

  • newInstance():通过 JDK 的 Proxy.newProxyInstance() 创建代理对象,该对象拦截方法调用并执行 SQL。
3.4 SqlSession

SqlSession 是 MyBatis 的核心接口,负责执行 SQL 语句和事务管理。

关键逻辑:

  • selectOne():执行单条查询。
  • insert():执行插入操作。
  • 事务管理:通过 commit()rollback() 管理事务。

4 知识点总结
  1. 动态代理实现:MyBatis 使用 JDK 动态代理为 Mapper 接口生成代理类,所有方法调用通过 MapperProxy.invoke 方法处理。
  2. MapperProxy 类:拦截方法调用,并通过 MapperMethod 执行 SQL。
  3. MapperMethod 类:负责接口方法与 SQL 语句的映射,执行 SQL 后处理结果。
  4. SQL 执行与封装:使用 SqlSession 执行 SQL,根据返回类型封装结果。

5 设计模式总结
5.1 代理模式 (Proxy Pattern)
  • 应用场景:用于为 Mapper 接口创建代理,实现 SQL 执行的动态绑定。
  • 优势:通过代理模式,开发者只需定义接口,无需实现具体的 SQL 执行逻辑。
5.2 工厂模式 (Factory Pattern)
  • 应用场景MapperProxyFactory 用来创建 MapperProxy,集中管理代理对象创建。
  • 优势:工厂模式简化了对象创建过程,提升了代码的可扩展性。
5.3 模板方法模式 (Template Method Pattern)
  • 应用场景MapperMethod.execute 是模板方法,封装 SQL 执行的通用流程。
  • 优势:提取通用逻辑,减少重复代码,提高可读性和扩展性。

本文作者:鸿·蒙

文档工具:Typora

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 鸿·蒙 !


http://www.kler.cn/a/403008.html

相关文章:

  • 「Mac玩转仓颉内测版23」基础篇3 - 深入理解整数类型
  • 14 go语言(golang) - 并发编程goroutine和channel
  • ROS机器视觉入门:从基础到人脸识别与目标检测
  • 影响电阻可靠性的因素
  • win10右键文件卡顿解决
  • 【Unity How】Unity中如何实现物体的匀速往返移动
  • Python实现随机分布式延迟PSO优化算法(RODDPSO)优化CNN分类模型项目实战
  • 2024.11|云计算行业的商业模式创新方法及实践
  • 【Python】selenium获取定位元素大小、电脑屏幕的像素、屏幕尺寸信息、以及网页尺寸的方法
  • Java EE 【知识改变命运】01计算机的一些知识点
  • 异常检测作业
  • ubuntu.24安装cuda
  • 导入JUnit测试类jar包
  • Java面试之多线程并发篇(6)
  • el-cascader 使用笔记
  • 探索Linux软件包管理的进化之路:从源码编译到Snap包的飞跃
  • Python实现图片定位与自动输入文字
  • 七、利用CSS和多媒体美化页面的习题
  • OLED透明屏在零售行业有什么应用场景
  • SpringBoot项目升级到3.*,并由JDK8升级到JDK21
  • [ 跨域问题 ] 前后端以及服务端 解决跨域的各种方法
  • FIFO架构专题-拼接方案及FIFO读清案例
  • 使用 Axios 拦截器优化 HTTP 请求与响应的实践
  • 论文阅读 SeedEdit: Align Image Re-Generation to Image Editing
  • 绿光一字线激光模组:工业制造与科技创新的得力助手
  • 下单抽奖领取商品奖品之后还能继续抽奖问题处理