小菜鸟

java菜鸟号正在起航

MyBatis MappedStatement 深度解析:Mapper 节点的 “配置容器” 与 SQL 执行的 “元数据核心”

在 MyBatis 中,MappedStatementMapper 配置(XML / 注解)与 SQL 执行之间的关键桥梁—— 它将 Mapper 中单个 SQL 节点(如 <select><insert>)的所有配置(SQL 语句、参数映射、结果映射、缓存策略等)封装为一个可执行的 “元数据对象”,是 MyBatis 解析配置、生成 SQL、执行查询的核心依据。从 “核心定位→属性解析→生命周期→实战关联” 四个维度,彻底拆解 MappedStatement 的作用与价值。

MappedStatement 核心定位:SQL 节点的 “配置容器”

MyBatis 启动时,会扫描所有 Mapper 接口和 XML 文件,将每个 SQL 节点(如 <select id="selectUserById"> 解析为一个 MappedStatement 对象,存储在 ConfigurationmappedStatements 集合中(keynamespace + id,如 com.example.UserMapper.selectUserById)。

MappedStatement 的核心作用是:

  1. 配置聚合:集中管理单个 SQL 节点的所有配置(SQL 语句、参数、结果、缓存等),避免配置分散;
  2. 元数据提供:为 Executor(执行器)、StatementHandler(SQL 处理器)等组件提供执行所需的全部元数据;
  3. 一致性保障:确保 SQL 执行过程中,参数绑定、结果映射、缓存策略等配置的一致性。

MappedStatement 核心属性解析

MappedStatement 的属性与 Mapper 节点的配置一一对应,每个属性都直接影响 SQL 的执行逻辑。按 “核心功能分组” 解析关键属性:

阅读全文 »

MyBatis 详细执行过程:从源码视角拆解核心流程

MyBatis 的执行过程本质是 “配置解析→核心对象创建→SQL 执行→结果封装” 的闭环,涉及 ConfigurationSqlSessionExecutorStatementHandler 等核心组件的协同工作。本文结合 MyBatis 3.5.x 源码,将执行过程拆解为 7 个关键步骤,每个步骤深入核心源码与组件职责,帮你彻底理解 MyBatis 的运行机制。

核心执行流程总览

MyBatis 从初始化到执行 SQL 的完整流程可概括为:
配置加载 → 创建 SqlSessionFactory → 创建 SqlSession → 获取 Mapper 代理 → 执行 SQL(Executor 调度) → 数据库交互(StatementHandler) → 结果封装(ResultSetHandler)

先通过一张简化的组件协作图理解核心关系:

执行过程

详细执行步骤(结合源码)

步骤 1:加载配置文件,初始化 Configuration 对象

MyBatis 启动时,首先解析 全局配置文件(mybatis-config.xml)所有 Mapper 映射文件(XxxMapper.xml),将配置信息统一封装到 Configuration 对象中(Configuration 是 MyBatis 的 “配置中心”,全局唯一)。

核心源码:SqlSessionFactoryBuilder.build()

SqlSessionFactoryBuilder 是创建 SqlSessionFactory 的入口,其核心逻辑是解析配置文件生成 Configuration

阅读全文 »

MyBatis 整合 Spring 完整指南:从 XML 配置到 Spring Boot 实践

MyBatis 与 Spring 的整合是企业级开发的主流方案,核心是将 MyBatis 的核心组件(SqlSessionFactoryMapper 代理)交给 Spring IOC 容器管理,同时复用 Spring 的事务管理、依赖注入等能力。 Spring Boot 注解式整合(主流方案)生产级数据源配置事务深化工程规范常见问题排查,覆盖传统 Spring 与 Spring Boot 两种场景。

版本选型与依赖优化

2024 年稳定版本组合(支持 Spring 5 特性,兼容 JDK 8+):

传统 Spring(XML 配置)依赖

<dependencies>
    <!-- MyBatis 核心 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.16</version>
    </dependency>
    <!-- MyBatis-Spring 整合包(2.x 支持 Spring 5) -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.1.6</version>
    </dependency>

    <!-- Spring 核心依赖(5.x 稳定版) -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.31</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.31</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.3.31</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.3.31</version>
        <scope>test</scope>
    </dependency>

    <!-- 生产级数据源(HikariCP,Spring 5 默认) -->
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>5.0.1</version>
    </dependency>
    <!-- MySQL 驱动(8.x 支持 MySQL 8.0+) -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>

    <!-- 测试依赖 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Spring Boot(注解式)依赖

Spring Boot 提供 mybatis-spring-boot-starter,自动整合 MyBatis 与 Spring,无需手动配置 SqlSessionFactoryMapperScanner,是当前主流方案:

阅读全文 »

MyBatis 缓存机制深度剖析与实践指南

MyBatis 的缓存机制是提升数据库访问性能的核心手段,通过减少重复查询来降低数据库压力。深入解析一级缓存、二级缓存的工作原理、适用场景、配置技巧及最佳实践,帮助你在实际项目中合理运用缓存提升系统性能。

缓存机制整体架构

MyBatis 缓存分为一级缓存二级缓存,两者在作用范围、生命周期和使用方式上有显著区别,但协同工作形成完整的缓存体系:

维度 一级缓存(Local Cache) 二级缓存(Global Cache)
作用范围 SqlSession 级别(单次会话) Mapper 接口(namespace)级别
默认状态 自动开启,无法关闭 需手动开启(全局 + 映射文件配置)
数据存储 内存 HashMap(无持久化) 可配置(内存 / 第三方缓存如 Redis)
共享性 仅当前 SqlSession 可见 同 SqlSessionFactory 下所有 SqlSession 共享
失效触发 SqlSession 关闭 / 提交 / 增删改操作 同 namespace 下增删改操作 / 缓存过期

MyBatis 缓存查询流程如下:

  1. 发起查询时,先检查二级缓存(若开启);
  2. 二级缓存未命中,检查一级缓存
  3. 一级缓存未命中,执行数据库查询;
  4. 查询结果依次写入一级缓存和二级缓存(若开启)。

一级缓存:SqlSession 级别的本地缓存

一级缓存是 MyBatis 内置的基础缓存,默认开启且无需额外配置,其核心作用是在单次数据库会话中复用查询结果。

工作原理

  • 存储结构:每个 SqlSession 内部维护一个 HashMap 作为缓存容器,键为 CacheKey,值为查询结果。
  • CacheKey 生成逻辑:由以下因素共同决定(任意一项不同则 CacheKey 不同):
    • MappedStatement 的 ID(即 namespace + methodName);
    • 分页参数(offset/limit);
    • SQL 语句本身;
    • 传入的参数值;
    • 数据库环境 ID(environment.id)。
  • 生命周期:与 SqlSession 一致,随 SqlSession 关闭而销毁。

一级缓存命中与失效示例

示例 1:一级缓存命中(同 SqlSession 内重复查询)
阅读全文 »

MyBatis 动态 SQL 详解与实战

动态 SQL 是 MyBatis 的核心特性之一,它允许我们根据不同条件动态构建 SQL 语句,有效解决了传统 SQL 拼接带来的语法错误(如多余的 AND、逗号等问题)。深入解析动态 SQL 标签的使用场景、最佳实践及高级技巧。

动态 SQL 核心标签详解

1. if 标签:条件判断

if 标签是动态 SQL 中最基础的条件判断标签,通过 test 属性(OGNL 表达式)决定是否拼接其内部的 SQL 片段。

基础用法
<select id="findUsers" resultType="User">
  SELECT * FROM users
  WHERE 1=1  <!-- 避免所有条件不满足时出现空 WHERE -->
    <if test="username != null and username != ''">
      AND username LIKE #{username}
    </if>
    <if test="age != null">
      AND age > #{age}
    </if>
    <if test="status != null">
      AND status = #{status}
    </if>
</select>
注意事项
  • test 属性中使用 OGNL 表达式,判断字符串非空需同时检查 != null!= ''
  • 数值类型只需判断 != null(避免 != 0 误判合法的 0 值);
  • 多条件判断可用 &&(需转义为 &&)或 and 连接。

2. where 标签:智能处理条件前缀

where 标签解决了 if 标签可能导致的「多余 AND/OR」问题,它会自动去除条件片段开头的 ANDOR,并在有条件时添加 WHERE 关键字。

替代 1=1 的优雅方案
阅读全文 »
0%