Mybatis源码分析——MappedStatement(2)

MyBatis 核心组件 MappedStatement 详解:一篇文章搞懂所有核心属性! 在 MyBatis 的底层架构中,有一个组件堪称“SQL执行的灵魂”——它就是 MappedStatement。无论是简单的 selectOne 还是复杂的动态 SQL,最终都要通过它来完成 SQL 解析、参数绑定、执行和结果映射。今天,我们就来深度拆解这个核心组件,把它的核心属性一次性讲透! 阅读详情

上一篇主要讲了MappedStatement基本概念,接下来主要分析动态sql语句怎么解析成MappedStatement。

在 MyBatis 中,动态 SQL 是指根据条件动态生成 SQL 语句的功能。动态 SQL 语句通常在 Mapper 文件中使用 <if>, <choose>, <when>, <otherwise>, <foreach> 等标签来实现。当 MyBatis 执行动态 SQL 时,它会将这些动态 SQL 解析成一个 MappedStatement 对象,然后通过 Executor 执行相应的 SQL。

1. 动态 SQL 的解析过程

动态 SQL 的解析主要是通过 SQL 构建器和动态 SQL 标签(如 <if>, <choose>, <when>, <foreach> 等)来实现的。MyBatis 在解析这些动态标签时,会生成相应的 SQL 语句,并将其包装成 MappedStatement 对象。

1.1. 动态 SQL 标签

在 MyBatis 的 XML 配置文件中,动态 SQL 是通过一组特定的标签来实现的。例如:

<select id="selectUsers" resultType="User">
    SELECT * FROM users
    <where>
        <if test="name != null">AND name = #{name}</if>
        <if test="age != null">AND age = #{age}</if>
    </where>
</select>

在上面的例子中,<if> 标签根据传入的条件来动态生成 SQL 语句。如果 name 不为空,则会生成 AND name = #{name} 部分;如果 age 不为空,则会生成 AND age = #{age} 部分。<where> 标签会根据是否有动态条件生成 WHERE 子句。

1.2. 动态 SQL 解析的关键组件

在 MyBatis 中,动态 SQL 的解析过程通常涉及以下几个步骤:

  1. SQL 源 (SqlSource) 的生成:

    • 在解析动态 SQL 时,MyBatis 会根据 Mapper 文件中的 XML 标签生成一个 SqlSource 对象。SqlSource 对象负责保存原始的 SQL 语句及其动态部分。它包含了 SQL 的模板(即静态部分)和动态 SQL 条件(即根据输入条件决定是否加入的部分)。
  2. DynamicSqlSource:

    • DynamicSqlSource 是 MyBatis 中处理动态 SQL 的类,它会将动态部分和静态部分结合起来,动态构建最终的 SQL 语句。
    • 在执行 SQL 时,DynamicSqlSource 会根据输入参数的不同,动态地生成最终的 SQL 语句。
  3. 生成 MappedStatement:

    • 在 Mapper 文件解析的过程中,MyBatis 会根据 id、SQL 类型、参数类型、返回类型等生成一个 MappedStatement。这个 MappedStatement 对象会包含对应的 SqlSource,它负责执行 SQL 查询时生成最终的 SQL 语句。

2. 动态 SQL 解析流程

以下是 MyBatis 解析动态 SQL 并生成 MappedStatement 的主要步骤:

2.1. 解析 Mapper 文件

当 MyBatis 启动时,SqlSessionFactory 会解析 Mapper 文件中的 SQL 映射语句(<select>、<insert>、<update>、<delete>)。在解析过程中,如果遇到动态 SQL 标签(如 <if>、<choose>、<foreach> 等),MyBatis 会调用相应的解析器来处理这些标签。

2.2. 生成 SqlSource

对于动态 SQL,MyBatis 会为每个动态 SQL 语句生成一个 SqlSource 对象。SqlSource 是 MyBatis 用来构建 SQL 的接口,它的实现类有:

  • StaticSqlSource:用于普通静态 SQL。
  • DynamicSqlSource:用于动态 SQL。

DynamicSqlSource 会在 SQL 执行时根据参数动态地生成最终的 SQL 语句。SqlSource 对象不仅包含了 SQL 的文本模板,还包含了如何根据输入参数动态生成 SQL 的逻辑。

2.3. 构建 MappedStatement

MappedStatement 是 MyBatis 中一个非常核心的类,它封装了与 SQL 执行相关的所有元数据(如 SQL、返回值类型、参数类型等)。MyBatis 会根据映射文件中的配置,构建一个 MappedStatement 对象。

以下是 MappedStatement 的构建过程:

MappedStatement.Builder builder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType);
builder.parameterMap(parameterMap);
builder.resultMaps(resultMaps);
MappedStatement mappedStatement = builder.build();
  • id:表示该映射语句的唯一标识符,通常是 SQL 语句的 id 属性。
  • sqlSource:表示 SQL 源,这里会传入动态 SQL 的 SqlSource。
  • sqlCommandType:SQL 执行类型,如 SELECT、INSERT、UPDATE、DELETE。
  • parameterMap:表示 SQL 语句的参数映射,描述如何将输入参数传递到 SQL 语句中。
  • resultMaps:表示 SQL 查询结果的映射,描述如何将查询结果转换为 Java 对象。
2.4. MappedStatement 注册到 Configuration 中

MyBatis 在解析所有 Mapper 文件时,会将生成的 MappedStatement 对象存储在 Configuration 的 mappedStatements 中,使用 SQL 语句的 id 作为键。这些 MappedStatement 对象将在 SQL 执行时被 Executor 用来执行具体的 SQL 操作。

2.5. 执行 SQL

在 Executor 执行 SQL 时,MappedStatement 会被检索到,并且通过 SqlSource 动态生成最终的 SQL 语句。Executor 根据生成的 SQL 执行查询、插入、更新等操作。

3. 动态 SQL 的实现机制

MyBatis 使用了 OGNL(Object-Graph Navigation Language)表达式语言来处理动态 SQL 标签中的条件判断。这使得 MyBatis 可以在 XML 文件中通过 OGNL 表达式来控制 SQL 语句的生成。

例如,在 <if> 标签中:

<if test="name != null">AND name = #{name}</if>

MyBatis 会解析 test="name != null" 中的 OGNL 表达式,判断 name 是否为 null,如果不为 null,则将 AND name = #{name} 这部分 SQL 添加到最终的 SQL 中。

4. SqlSource 的解析

SqlSource 是 MyBatis 动态 SQL 的核心接口,MyBatis 提供了两种实现类:

  • StaticSqlSource:用于静态 SQL 查询,它只是将 SQL 作为字符串保存。
  • DynamicSqlSource:用于动态 SQL 查询,负责根据参数动态生成 SQL。

DynamicSqlSource 是 MyBatis 处理动态 SQL 的关键类,它会解析动态 SQL 标签并根据实际的条件构建最终的 SQL。

动态 SQL 示例:DynamicSqlSource 处理过程

假设你有以下的动态 SQL 语句:

<select id="selectUser" resultType="User">
    SELECT * FROM user
    <where>
        <if test="name != null">AND name = #{name}</if>
        <if test="age != null">AND age = #{age}</if>
    </where>
</select>
  1. DynamicSqlSource 创建:在解析过程中,MyBatis 会根据这个 SQL 语句创建一个 DynamicSqlSource 对象。
  2. SqlNode 解析:DynamicSqlSource 会将 XML 中的 SQL 语句分解成多个 SqlNode,例如 <where> 和 <if> 标签会分别转换成 WhereSqlNode 和 IfSqlNode。
  3. SQL 拼接:当调用 SQL 时,DynamicSqlSource 会检查输入的参数,执行 OGNL 表达式,决定是否将每个动态部分(如 AND name = #{name})添加到最终的 SQL 语句中。

5. 总结

  • 动态 SQL 是 MyBatis 中根据条件动态生成 SQL 语句的功能,通常通过 <if>、<choose>、<foreach> 等标签来实现。
  • MyBatis 通过 SqlSource 来构建 SQL,DynamicSqlSource 会根据动态标签生成最终的 SQL 语句。
  • MappedStatement 是 MyBatis 中封装 SQL 语句、参数类型、返回类型等元数据的对象,它包含了动态 SQL 语句的生成逻辑和执行信息。
  • 解析后的 MappedStatement 会被 Executor 执行,最终根据不同的输入参数动态生成并执行 SQL。

动态 SQL 的解析过程是 MyBatis 强大功能的核心之一,通过灵活的 XML 标签和 OGNL 表达式,MyBatis 能够根据不同的业务需求生成灵活的 SQL 查询。

Mybatis3源码分析(05)-加载Configuration-加载MappedStatement XMLStatementBuilder.parseStatementNode()方法 resultMap元素的解析已经分析完毕。与resultMap不一样,XmlMapperBuilder在解析select/update/insert/delete的元素时会创建一个XMLStatementBuilder对象,解析的工作交由其方法parseStatementNode()方法完成。private v 阅读详情

相关推荐

mybatis源码,从配置到 mappedStatement —— mapper.xml 是如何被解析的?

个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈 Ext1:本文源码解析基于 mybatis-spring-boot-starter 2.1.1,即 mybatis 3.5.3 版本。 Ext2:本文主要是对源码的讲解,着重点会是在源码上。 一、从 MybatisAutoConfiguration 说开去,mapper 文件是怎么扫描的? 我们知道配置SqlSes...

JKX_geek的博客 1041

Mybatis 源码分析 —— MappedStatement 解析

解析 xml 生成对应 mappedStatement 的流程分析。

一步一步往上爬 1万+

MyBatis源码分析

篇章一:入口篇 我们学习Mybatis时知道其核心是SqlSessionFactory,它是mybatis的核心类,也是Mybatis运行的入口,spring集成mybatis时需要配置SqlSessionFactoryBean和扫描mapper的MapperScannerConfigurer,spring-mybatis集成主要的配置就这么点,从这理解也就不难理解mybatis入口问题了,但是...

简乐君 1万+

Mybatis MappedStatement

MappedStatement 类是 Mybatis 框架的核心类之一,它存储了一个 sql 对应的所有信息 Mybatis 通过解析 XML 和 mapper 接口上的注解,生成 sql 对应的 MappedStatement 实例,并放入 SqlSessionTemplate 中 configuration 类属性中 正真执行 mapper 接口中的方法时,会从 configuration 中找到对应的 mappedStatement,然后进行后续的操作

qq_37436172的博客 2993

Mybatis源码分析篇

在上几篇文章中大致介绍了mybatis的作用和用法。本篇主要对mybatis的源码做一个分析。而在源码分析之前,需要重点介绍mybatis几个重要的类:SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Configuration、MappedStatement、SqlSource、LanguageDriver、KeyGenerator、Executor;每个类都有各自的角色职责。});

YaYicho的博客 736

NIDS——suricata(一)

NIDS——suricata环境安装和规则编写

weixin_58666006的博客 1273

MappedStatement 分析

采用#{var}的形式来引用变量时,其中的变量会在解析Mapper.xml文件中的语句时,就被替换成占位符“?上述方法主要是对动态标签的解析,获取完全可执行的sql。若上传多个参数对象时:为ParamMap对象,由于我们使用了@Param注解,故可以使用注解的key,也可以使用param1取出变量。该对象为sql执行的参数。注意:ParameterObject是一个Object对象,上传不同的参数时,该对象的类型不同。BoundSql对象中的sql对象是对动态标签解析后的完全可执行的sql。

qq_44021627的博客 1128

论文分享 - OctoMap八叉树建图原理

论文:OctoMap:An Efficient Probabilistic 3D Mapping Framework Based on Octrees。

一只废佐_的博客 2541

Mybatis 源码 MappedStatement原理

Mybatis在sping boot 启动的时候,会自动装配,其中包含重要的属性,Configuration里面的MappedStatement,封装了xml里面的所有select|insert|update|delete信息。 本文以mybatisplus为例 MybatisPlusAutoConfiguration 首先加入mybatisplus的依赖后,sping boot找到com.baodidou.mybatisplus.autoconfigure包下面的META-INF/spring.fa

CarryBest的博客 2535

保姆级教程:在Windows上用Python+OpenCV调用海康工业相机(附MVS配置避坑指南)

本文提供了一份详细的Windows环境下使用Python和OpenCV调用海康工业相机的保姆级教程,涵盖MVS配置避坑、相机连接、图像获取与格式转换等关键步骤。特别针对工业相机取流中的常见问题,如独占访问控制和多相机协同工作,提供了实用解决方案,帮助开发者快速实现稳定的图像采集系统。

weixin_29228781的博客 401

SuccessFactors入门篇

SuccessFactors入门篇—— Employee Central(一)最近通过一个月左右的学习,拿到了SF EC(SuccessFactors Employee Central )模块SAP认证,所以打算把自己学习SF的整个过程以及相关资料和大家分享一下,相互切磋,共同进步。Employee Central简单了解Employee Central简单了解新的改变功能快捷键合理的创建标题,有...

qq_42288853的博客 1万+

源码分析Mybatis MappedStatement的创建流程

本文是Mybatis源码分析第二篇,重点分析Mybatis Mapper.java是如何与mapper.xml文件中的SQL建立联系,即MappedStatement对象的创建流程。1、源码分析Mybatis MapperProxy创建流程;源码分析Mybatis MappedStatement的创建流程;3、源码解析MyBatis Sharding-Jdbc SQL语句执行流程详解;4、源码分析Mybatis插件(Plugin)机制;5、源码分析Mybatis一二级缓存

中间件兴趣圈 5875

Spark中Application、Job、Stage和Task区别详解

在Spark中,有一些关键的概念,如Application、Job、Stage和Task,它们描述了Spark作业的不同层次和组成部分。下面我将详细介绍每个概念,并通过示例说明它们之间的区别。

优快云 精品推荐 907

Mybatis-Spring源码分析(五) MapperMethod和MappedStatement解析

基本上这就是Mybatis-Spring源码的最后一篇了,如果想起来什么再单开博客。比起来Spring源码,Mybatis的确实简单一些,本篇就说一下Mybatis中两个十分重要的类MapperMethod,MappedStatement以及其在Mybatis的流程中的主要作用。

Smallc0de的博客 4369

S7-200 SMART PLC 数字量阀门控制功能块(FB)汇总

S7-200 SMART PLC功能块的各种写法可以查看专栏的其它文章,链接地址如下:S7-200 SMART PLC 子程序功能块(阀门控制)_RXXW_Dor的博客-优快云博客_plc控制阀门开关程序由于S7-200 SMARTPLC的子程序种种功能、容量限制,有时想实现多次调用的子程序可能并不是太容易,这篇博客还是给出一些推荐写法,供大家参看。

RXXW_Dor的博客 4003

硬件工程师学习-硬件的单元测试(UT)(1)电源与时钟的测试

我们在设计的时候,通过控制电源的上电使能管脚或者通过MOSFET、或者专用的电源上电控制芯片,控制不同电源的上电时序,以确保每个芯片的电源上电时序是满足芯片的要求的。我们在测试的时候,需要对相关的要求一一测试,以确认每个上电时序满足要求的。在维基百科中,相位噪声的定义是“时域不稳定性(抖动)导致波形在相位上发生快速、短期、随机的波动,这种波动在频域中的表现即为相位噪声”。单元测试,一般是指基于开发人员自行开展的功能测试及各个功能单元的单元测试,是硬件信号级的测试,分为基本测试和信号完整性测试。

qq_43416206的博客 4037

Mybatis源码分析——MappedStatement(1)

在 MyBatis 中,每个 SQL 映射语句(如。

java_xiaowangzi的博客 1077

动态视频目标追踪系统:基于YOLOv11+DeepSORT的从入门到实战全流程指南

仅保留车辆类别(假设车辆类别ID为2)if det.class_index == 2: # 车辆类别ID通过本指南,你已完成从环境搭建数据准备模型训练到追踪系统与UI界面的全流程,搭建了一套完整的动态视频目标追踪系统。该系统在安防监控、交通管理等场景中具有实用价值,可实现目标的实时稳定追踪。未来,你可尝试结合多模态特征(如目标外观+运动特征)提升追踪鲁棒性,或探索轻量化模型部署(如TensorRT加速),让系统在边缘设备上也能高效运行。

LXY_LOVE36的博客 142

mybatis中MappedStatement注入到StrictMap过程

MappedStatement注入到StrictMap(mappedStatements)

zys1440298847的博客 551

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Mybatis 源码分析 —— 运行流程解析

mybatis 运行各节点流程归纳。

一步一步往上爬 669

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Mybatis 核心源码分析

一、Mybatis 整体执行流程 二、Mybatis 层次结构 三、源码分析

Julie的博客 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

mybatis plus 批量保存_mybatis源码分析

原理图:Configuration解析:Configuration表示配置,该对象中维护了很多mybatis的配置参数;大致可分为四部分:1.环境变量Environment 2.配置参数;3.缓存集合;4.插件及其他1.1环境变量EnvironmentEnvironment.java源码通过Environment源码可以看出,Environment仅维护了一个id 唯一标识,Transaction...

weixin_39866966的博客 2062

MyBatis工作原理源码分析(一)——SqlSessionFactory的初始化

SqlSessionFactory的初始化

scorpio的博客 1527

MyBatis源码分析——使用注解执行SQL

文章目录MyBatis源码分析使用注解方式执行SQL相关参考 MyBatis源码分析 使用注解方式执行SQL 使用注解执行SQL只需在自定义Mapper接口上添加注解如@Select、@Insert、@Update、@Delete等,示例如下: public interface UserMapper { @Select("select * from user where id = #{id}"...

SK_Jaco的博客 1838

Mybatis源码分析(自己动手造轮子)

个人博客欢迎访问 总结不易,如果对你有帮助,请点赞关注支持一下 目录Mybatis基础概念缓存简介一级缓存二级缓存高级查询建表一对一查询联合查询嵌套查询一对多查询扩展问题#{}和${}的区别什么是Sql注入为什么需要预编译通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?MyBatis源码Mybatis的编程步骤Mybatis的工作原理Mybatis的功能架构配置文件解析过程配置文件解析入口解析 environmen

qq_45796208的博客 2758

MyBatis源码分析——使用SqlSession操作数据库

文章目录MyBatis源码分析使用SqlSession操作数据库SqlSession自带方法整体操作流程相关参考 MyBatis源码分析 使用SqlSession操作数据库 MyBatis执行数据库操作主要分为三种:使用SqlSession自带方法、调用Mapper接口方法执行SQL、使用注解执行SQL SqlSession自带方法 在示例代码中使用了SqlSession.selectOne()方...

SK_Jaco的博客 3378
上一篇: Mybatis源码分析——MappedStatement(1)
下一篇: Mybatis源码分析——Executor
yang_xinkun
博客等级 码龄10年 108粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值