Mybatis 与 Springboot 集成过程详解

发布于:2025-08-29 ⋅ 阅读:(16) ⋅ 点赞:(0)

一. 核心概念与优势

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

  • 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 框架的标志性特性

三.参考图

在这里插入图片描述