Mybatis 与 Springboot 集成过程详解

Mybatis 与 Springboot 集成过程详解

  • 一. 核心概念与优势
  • 二.Mybatis 核心类简介
    • 1.MybatisAutoConfiguration
    • 2.MapperScans
    • 3.MapperScannerRegistrar
    • 4.MapperFactoryBean
    • 5.Configuration
    • 6.MapperRegistry
    • 7.MapperProxy 与 MapperProxyFactory
      • 7.1核心定位与职责
      • 7.22. ​​MapperProxy(动态代理处理器)​​
      • 7.3 协作流程与执行机制
  • 三.参考图

一. 核心概念与优势

在开始之前,先快速了解为什么这种集成如此流行:

  • MyBatis​​: 一个优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。它避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

  • Spring Boot​​: 旨在简化 Spring 应用的初始搭建和开发过程,提供了大量的自动配置。

  • 集成优势​​:

    • ​​简化配置​​: Spring Boot 为 MyBatis 提供了官方 starter,极大减少了 XML 配置。

    • ​​自动装配​​: 自动配置 SqlSessionFactory、SqlSessionTemplate、DataSource等 bean。

    • ​​无缝整合​​: 与 Spring 的事务管理、AOP 等特性完美结合

二.Mybatis 核心类简介

1.MybatisAutoConfiguration

MybatisAutoConfiguration 是 MyBatis Spring Boot Starter 的核心自动配置类,通过 META-INF/spring.factories文件注册到 Spring 容器中。当应用启动时,@EnableAutoConfiguration会触发其加载,前提是满足以下条件:

  • 类路径存在 SqlSessionFactory和 SqlSessionFactoryBean(确保 MyBatis 核心依赖已引入)。

  • 容器中存在​​唯一的数据源 Bean​​(依赖 DataSourceAutoConfiguration完成数据源配置)。

  • 在数据源配置完成后执行(通过 @AutoConfigureAfter(DataSourceAutoConfiguration.class)控制加载顺序)

2.MapperScans

基本功能与作用
.
1.批量扫描注册

  • 自动扫描指定包路径下的 Mapper 接口,生成 BeanDefinition并注册到 Spring 容器。

  • 避免在每个 Mapper 接口上单独添加 @Mapper注解,简化配置。

2.支持多路径与通配符

  • 支持数组形式指定多个包路径(如 @MapperScan({“com.dao.user”, “com.dao.product”}))。

  • 支持通配符匹配(如 com.example.*.mapper扫描一级子包,com.example.**.mapper扫描多级子包)。

3.多数据源适配

  • 结合 sqlSessionFactoryRef或 sqlSessionTemplateRef属性,为不同数据源指定独立的 SQL 会话工厂或模板

核心属性解析

属性名功能说明示例
value/ basePackages指定扫描的包路径(支持数组)@MapperScan(“com.dao”)
basePackageClasses通过类的包路径定位扫描范围(类型安全)@MapperScan(basePackageClasses=UserMapper.class)
annotationClass仅扫描带有指定注解的接口(默认扫描所有接口)annotationClass = Repository.class
markerInterface仅扫描继承指定父接口的接口markerInterface = BaseMapper.class
sqlSessionFactoryRef指定多数据源下使用的 SqlSessionFactoryBean 名称sqlSessionFactoryRef = “ds1SqlSessionFactory”
factoryBean自定义 MapperFactoryBean实现类(需继承 MapperFactoryBean)factoryBean = CustomMapperFactoryBean.class

3.MapperScannerRegistrar

核心定位与作用
1.注解解析枢纽
@MapperScan注解通过 @Import(MapperScannerRegistrar.class)引入该类,使其成为 Spring 容器启动时处理 Mapper 扫描配置的入口点。
2.动态注册引擎
实现 ImportBeanDefinitionRegistrar接口,在 Spring 容器初始化阶段动态注册 MapperScannerConfigurer的 BeanDefinition,从而将用户配置(如包路径、过滤条件)转化为 Spring 可执行的扫描任务。
3.多数据源适配桥梁
支持通过 sqlSessionFactoryRef或 sqlSessionTemplateRef属性关联特定数据源,解决多数据源场景下 Mapper 与 SQL 会话工厂的绑定问题

核心实现机制

  1. 注解属性解析
  • 读取 @MapperScan中的 basePackages、basePackageClasses等属性,构建待扫描的包路径列表。
  • 解析过滤条件(如 annotationClass、markerInterface),定制扫描范围。
  1. ClassPathMapperScanner 初始化
    创建 ClassPathMapperScanner对象(继承自 Spring 的 ClassPathBeanDefinitionScanner),并配置其属性:
  • 设置资源加载器(ResourceLoader)
  • 注入自定义的 Bean 名称生成器(BeanNameGenerator)
  • 定 Mapper 代理工厂类(MapperFactoryBean)。
  1. 接口扫描与代理转换
    调用 scanner.doScan()方法扫描目标包路径,通过重写 isCandidateComponent()确保仅扫描接口类型:扫描完成后,将接口的 BeanDefinition 替换为 MapperFactoryBean类型,并注入构造参数(原接口类名),为后续动态代理奠基
  • ClassPathMapperScanner
  • 应用启动时,实际注入到服务层的Mapper接口,就是这个转换后的代理类实例

4.MapperFactoryBean

MapperFactoryBean→ SqlSessionDaoSupport→ DaoSupport

MapperFactoryBean 是 MyBatis-Spring 整合的核心组件,负责将 MyBatis 的 Mapper 接口动态代理并注册为 Spring 容器中的 Bean,从而简化数据访问层的开发。其设计基于 Spring 的 FactoryBean接口,实现了接口代理与资源管理的自动化

1.​​动态代理生成​​

MapperFactoryBean 通过 JDK 动态代理技术,为 Mapper 接口创建代理对象。当调用接口方法时,代理对象将请求转发给 MyBatis 的 SqlSession,执行对应的 SQL 操作。​​无需手动编写实现类​​,显著减少冗余代码

2.资源生命周期管理​​

自动管理 SqlSession的开启、关闭及事务控制:

  • 会话绑定​​:确保每次操作在正确的 SqlSession中执行。
  • ​​事务集成​​:与 Spring 事务管理器协同,支持声明式事务(如 @Transactional)。

3.异常转换​​
将 MyBatis 的 PersistenceException转换为 Spring 的 DataAccessException体系,统一异常处理

MapperFactoryBean 是 MyBatis-Spring 整合的​​动态代理枢纽​​,通过三大核心能力简化开发:

  • 自动化代理生成​​:消除 DAO 实现类,直接操作接口。
  • 资源管理集成​​:无缝管理 SqlSession生命周期与 Spring 事务。
  • 灵活配置扩展​​:支持 XML 显式声明或注解批量扫描,适配单数据源与多数据源场景

5.Configuration

全类名:org.apache.ibatis.session.Configuration

1.全局配置容器
Configuration对象在 MyBatis 初始化时创建(通常通过解析 mybatis-config.xml或 Java API 构建),集中存储以下配置:

  • 环境信息():包含数据源(DataSource)和事务管理器(TransactionFactory),支撑数据库连接与事务控制。
  • 全局设置():如 cacheEnabled(二级缓存开关)、lazyLoadingEnabled(延迟加载)、mapUnderscoreToCamelCase(下划线转驼峰)等运行时行为开关。
  • 注册中心:管理类型别名(TypeAliasRegistry)、类型处理器(TypeHandlerRegistry)、插件(InterceptorChain)等扩展点。

2.SQL 语句管理中心
维护关键映射组件的注册表,以 Map结构存储:

  • mappedStatements:管理所有 SQL 操作(Select/Insert/Update/Delete),Key 为 SQL 语句 ID(如 “com.example.UserMapper.selectById”)。
  • resultMaps:存储结果集映射规则()。
  • caches:管理命名空间级别的二级缓存。

3.核心组件工厂
提供方法创建 MyBatis 执行链的关键对象:

  • newExecutor():生成 Executor(SQL 执行器),支持 SIMPLE、REUSE、BATCH三种模式。
  • newStatementHandler():创建 StatementHandler(处理 JDBC Statement)。
  • newParameterHandler()/ newResultSetHandler():处理参数绑定与结果集映射

Configuration作为 MyBatis 的​​配置中枢与运行时引擎​​,通过三大核心能力支撑框架运作:

1.统一配置管理​​:整合 XML/注解/Javaconfig 配置源,提供全局访问接口。
2.组件调度工厂​​:动态创建 Executor、StatementHandler等核心执行链对象。
3.​​扩展性基石​​:通过拦截器链(InterceptorChain)和类型处理器(TypeHandlerRegistry)支持深度定制

6.MapperRegistry

MapperRegistry是 MyBatis 框架中​​管理 Mapper 接口注册与代理对象生成的核心组件​​,作为 MyBatis 配置中枢 Configuration的一部分,它在框架启动时初始化,并在运行时支撑面向接口的数据库操作模式。

核心作用与定位​​

1.​​Mapper 接口的注册中心​​

MapperRegistry集中管理所有需被 MyBatis 识别的 Mapper 接口,确保接口与 SQL 映射的关联。它通过内部维护的映射表 knownMappers(类型为 Map<Class<?>, MapperProxyFactory<?>>)实现:
​​Key​​:Mapper 接口的 Class对象(如 UserMapper.class)。
​​Value​​:为该接口创建的代理工厂 MapperProxyFactory,用于生成动态代理对象。

2.​​动态代理对象的提供者​​

当调用 sqlSession.getMapper(UserMapper.class)时,SqlSession委托 MapperRegistry查找接口对应的 MapperProxyFactory,并生成代理对象。此代理对象拦截接口方法调用,将其转化为 SQL 执行逻辑。

3.​​接口与 SQL 映射的绑定枢纽​​

在注册阶段,MapperRegistry触发注解或 XML 的解析(通过 MapperAnnotationBuilder),将接口方法关联到具体的 SQL 语句(MappedStatement),实现​​方法调用 → SQL 执行​​的动态绑定

MapperRegistry是 MyBatis ​​面向接口编程的基石​​,通过三层次协作实现高效数据访问:
1.​​注册层​​:统一管理 Mapper 接口,关联代理工厂。
2.​​代理层​​:动态生成代理对象,拦截方法调用。
3.执行层​​:将方法调用路由至 SqlSession,执行具体 SQL

7.MapperProxy 与 MapperProxyFactory

MapperProxy 与 MapperProxyFactory 是 MyBatis 实现 ​​Mapper 接口动态代理​​的核心组件,二者协同完成接口方法与 SQL 语句的绑定,使开发者无需编写实现类即可操作数据库

7.1核心定位与职责

  1. ​​MapperProxyFactory(代理对象工厂)​​
  • ​​职责​​:
    负责生产 Mapper 接口的代理对象实例(MapperProxy)。每个 Mapper 接口对应一个独立的 MapperProxyFactory实例。
  • ​​关键属性​​:
    • mapperInterface:需代理的 Mapper 接口 Class 对象(如 UserMapper.class)
    • methodCache:缓存接口方法与 MapperMethod的映射,避免重复解析

7.22. ​​MapperProxy(动态代理处理器)​​

  • 职责​​:
    实现 InvocationHandler接口,拦截 Mapper 接口方法调用,将其转换为底层 SQL 执行逻辑。
  • ​​关键依赖​​:
    • SqlSession:执行 SQL 的会话对象。
    • methodCache:缓存方法对应的 MapperMethod,优化性能。
  • ​​代理控制逻辑​​:
    • ​​Object 原生方法​​(如 toString):直接调用原生实现。
    • 接口默认方法​​:调用默认方法实现。
    • ​​抽象方法​​:委托给 MapperMethod执行 SQL

7.3 协作流程与执行机制

代理对象生成流程

1.注册阶段:
MyBatis 启动时通过 MapperRegistry扫描并注册所有 Mapper 接口,为每个接口创建 MapperProxyFactory实例。
2.调用阶段:
用户调用 sqlSession.getMapper(UserMapper.class):

  • MapperRegistry查找接口对应的 MapperProxyFactory。
  • MapperProxyFactory生成代理对象(内部创建 MapperProxy并绑定至接口)。
  1. 方法拦截与 SQL 执行
    当调用代理对象的接口方法(如 userMapper.selectById(1)):
    1.方法拦截:
    MapperProxy.invoke()拦截调用,跳过非抽象方法(如 Object方法)。
    2.方法映射:
    通过 cachedMapperMethod()获取或创建 MapperMethod对象(封装 SQL 语句、参数映射、返回类型)。
    3.SQL 执行:
    MapperMethod.execute()根据操作类型(SELECT/UPDATE)调用 SqlSession的对应方法(如 selectOne()),并返回结果

总结

  • MapperProxyFactory​​ 是代理对象的​​生产引擎​​,通过工厂模式屏蔽动态代理的复杂性。
  • ​​MapperProxy​​ 是代理逻辑的​​执行枢纽​​,将接口方法调用转化为 SQL 会话操作,实现 ORM 的“接口即实现”范式
  • ​​协同价值​​:二者通过动态代理机制,彻底解耦接口定义与 SQL 执行,成为 MyBatis 简化 DAO 层开发的核心设计,也是其区别于传统 ORM 框架的标志性特性

三.参考图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/97186.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/97186.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

prometheus alertmanager 对接飞书

alertmanager 直接配置 飞书 的 webhook &#xff0c;发现并不满足飞书接口的 json 格式。报错如下levelerror ts2025-08-28T04:57:02.734Z callerdispatch.go:310 componentdispatcher msg"Notify for alerts failed" num_alerts23 err"prometheusalert-webhoo…

『专利好药用力心脑血管健康』——爱上古中医(28)(健康生活是coder抒写优质代码的前提条件——《黄帝内经》伴读学习纪要)

心脏血管三通康&#xff0c;古时丸药精益装。 笔记模板由python脚本于2025-08-26 18:25:03创建&#xff0c;本篇笔记适合喜欢日常保健养生知识的coder翻阅。 学习的细节是欢悦的历程 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅仅是知识的简单复述。 Pyth…

在 .NET 8.0 中实现 JWT 刷新令牌

介绍在 Web 开发领域&#xff0c;安全是重中之重。JSON Web Tokens (JWT) 已成为在各方之间安全传输信息的热门选择。然而&#xff0c;在 JWT 过期后&#xff0c;如何维护用户会话并避免频繁登录至关重要。这正是 JWT 刷新令牌应运而生的地方。在本文中&#xff0c;我们将指导您…

深入解析 git push 命令

1. 基础语法 git push 的基本语法如下: git push <远程仓库名> <本地分支名>:<远程分支名> [选项]<远程仓库名>: 通常是 origin(默认的远程仓库名称)。 <本地分支名>:<远程分支名>: 指定要推送的本地分支以及目标远程分支。如果省略远…

UI弹出动画

简介的UI弹出动画 使用方式很简单 挂载到需要弹出的目标 即可 using UnityEngine; using DG.Tweening; using Unity.VisualScripting;/// <summary>/// 简洁的UI动画脚本/// 直接挂载到UI组件上&#xff0c;调用Play()播放缩放弹出动画/// </summary>public class …

PostgreSQL诊断系列(6/6):配置项全景解析——打造你的专属优化清单

&#x1f517; 作为《PostgreSQL诊断系列》的收官之作&#xff0c;今天我们系统梳理 postgresql.conf 中的核心参数&#xff0c;将前5篇的“诊断”转化为“调优”&#xff0c;打造一套生产环境专属的配置模板。 你是否&#xff1a; 不知道哪些参数该调&#xff1f;害怕调错导致…

Flink Slot 不足导致任务Pending修复方案

当前有3个虚拟机节点&#xff0c;每个节点配置的slot节点数量是4&#xff0c;${FLINK_HOME}/conf/flink-conf.yaml 关于slot的配置如下&#xff1a; # The number of task slots that each TaskManager offers. Each slot runs one parallel pipeline. taskmanager.numberOfTas…

亚马逊合规风控升级:详情页排查与多账号运营安全构建

2025年亚马逊掀起的大规模扫号行动&#xff0c;聚焦商品详情页合规性审查&#xff0c;标志着跨境电商合规监管进入严风控时代&#xff0c;此次行动以关键词规范与定价诚信为核心&#xff0c;大量卖家因内容违规遭遇账号停用&#xff0c;对于卖家而言&#xff0c;构建系统化的合…

FISCO-BCOS-Python 模板

基于Python-SDK的FISCO BCOS区块链HelloWorld模板&#xff0c;提供了简单的问候语设置和查询功能。本项目采用现代Python开发实践&#xff0c;包含完整的配置管理、测试框架和项目结构。 快速开始 仓库地址&#xff1a;git clone https://gitee.com/atanycosts/python-fisco-te…

移动端(微信等)使用 vConsole调试console

本文介绍了一种在移动端真机上进行调试的方法——使用VConsole。通过简单的安装步骤和代码配置&#xff0c;开发者可以在移动端直接查看console.log输出&#xff0c;极大提升了调试效率。 摘要生成于 C知道 &#xff0c;由 DeepSeek-R1 满血版支持&#xff0c; 前往体验 >作…

云计算资源分配问题

这里写目录标题一、云计算资源的基本类型二、资源分配的目标三、资源分配的方式四、资源分配的技术与工具五、挑战与优化方向六、实际应用场景举例总结云计算资源分配是指在云计算环境中&#xff0c;根据用户需求、应用程序性能要求以及系统整体效率&#xff0c;将计算、存储、…

深度学习之第二课PyTorch与CUDA的安装

目录 简介 一、PyTorch 与 CUDA 的核心作用 1.PyTorch 2.CUDA 二、CUDA的安装 1.查看 2.下载安装 3.检查是否安装成功 三、PyTorch的安装 1.GPU版本安装 2.CPU版本安装 简介 在深度学习的实践旅程中&#xff0c;搭建稳定且高效的开发环境是一切实验与项目的基础&…

Ubuntu22.04 安装和使用标注工具labelImg

文章目录一、LabelImg 的安装及配置1. 安装2. 配置二、使用1. 基础操作介绍2. 创建自定义标签2.1 修改 predefined_classes.txt2.2 直接软件界面新增3. 图像标注3.1 重命名排序3.2 标注3.2 voc2yolo 格式转换3.3 视频转图片Yolo系列 —— Ubuntu 安装和使用标注工具 labelImgYo…

Jenkins与Docker搭建CI/CD流水线实战指南 (自动化测试与部署)

更多云服务器知识&#xff0c;尽在hostol.com你是否已经厌倦了那个“人肉”部署的重复循环&#xff1f;每一次 git push 之后&#xff0c;都像是一个庄严的仪式&#xff0c;你必须虔诚地打开SSH&#xff0c;小心翼翼地敲下一连串的 git pull, npm install, docker build, docke…

【数据可视化-100】使用 Pyecharts 绘制人口迁徙图:步骤与数据组织形式

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

5G相对于4G网络的优化对比

5G网络作为新一代移动通信技术&#xff0c;相比4G实现了全方位的性能提升和架构优化。5G通过高速率、低时延和大连接三大核心特性&#xff0c;有效解决了4G网络面临的数据流量爆炸式增长和物联网应用瓶颈问题 &#xff0c;同时引入了动态频谱共享、网络切片等创新技术&#xff…

AR智能巡检:智慧工地的高效安全新引擎

在建筑行业,工地安全管理与施工效率的提升一直是核心议题。随着增强现实(AR)技术的快速发展,AR智能巡检系统正逐步成为智慧工地的“标配”,通过虚实结合、实时交互和智能分析,推动建筑行业迈入数字化、智能化的新阶段。本文将从技术原理、应用场景、核心优势及未来趋势等…

TypeScript:枚举类型

1. 什么是枚举类型&#xff1f;枚举&#xff08;Enum&#xff09;是TypeScript中一种特殊的数据类型&#xff0c;用于定义一组命名的常量值。它允许开发者用一个友好的名称来代表数值或字符串&#xff0c;避免使用“魔法数字”或硬编码值。基本语法&#xff1a;enum Direction …

Maven 编译打包一个比较有趣的问题

前言最近做项目&#xff0c;发现一个比较有意思的问题&#xff0c;其实发现了问题的根源还是很好理解&#xff0c;但是如果突然看到会非常的难以理解。在Java项目中&#xff0c;明明包名错误了&#xff0c;居然可以正常编译打包&#xff0c;IDEA报错了&#xff0c;但是mvn命令正…

Leetcode贪心算法

题目&#xff1a;划分字母区间 题号&#xff1a;763class Solution {public List<Integer> partitionLabels(String s) {List<Integer> list new LinkedList();int[] edge new int[27];char[] chars s.toCharArray();for(int i 0; i <chars.length;i){edge…