MyBatis:动态SQL高级标签使用方法指南
一、引言
目前互联网大厂在搭建后端Java服务时,常使用Springboot搭配Mybatis/Mybatis-plus的框架。Mybatis/Mybatis-plus之所以能成为当前国内主流的持久层框架,与其本身的优点有关:支持定制动态 SQL、存储过程及高级映射,简化数据库操作。
可能有人会问, 为什么要用动态SQL,在开发过程中把SQL写死不是比较方便、更加不容易出错吗?其实这是由开发过程中具体业务需求决定的,比如在用户注册场景下,用户注册填写信息时,会有必填字段和非必填字段,不同用户注册时传给后端的参数有区别,对应的插入用户表的SQL也不一样,因此,在这些的场景下开发人员需要使用动态SQL来完成。本文首先介绍Springboot项目中SQL映射方式,最后介绍动态SQL和支持动态SQL的核心标签。
欢迎关注工 众号:ItBeeCoder,查看更多高质量技术文章,发送“后端”获取资料
二、SQL映射方式
1、XML映射文件,该文件通常位于 resources/自定义的包路径/mapper 目录。
示例:
<!-- UserMapper.xml --><mapper namespace="com.example.UserMapper"><select id="selectUserById" resultType="User">SELECT * FROM user WHERE id = #{id}</select></mapper>
2、注解映射
适用场景:简单 SQL 可直接在接口方法上使用注解。
示例:
public interface UserMapper {@Insert("INSERT INTO user(name) VALUES(#{name})")@Options(useGeneratedKeys = true, keyProperty = "id")void insertUser(User user);}
欢迎关注工 众号:ItBeeCoder,查看更多高质量技术文章,发送“后端”获取资料
三、动态SQL及常用标签
在 MyBatis中,动态SQL允许开发人员根据不同的条件构建不同的 SQL 语句。执行原理为,使用OGNL从SQL参数对象中计算表达式的值,根据表达式的值动态拼接SQL,以此来完成动态SQL的功能。动态SQL中常用的核心标签有:、、、、、等。
1、动态 SQL
- 以下SQL为XML文件中复杂动态SQL的示例:
<select id="searchUsers" resultType="User">SELECT * FROM user<where><if test="name != null">AND name LIKE CONCAT('%', #{name}, '%')</if><if test="roles != null">AND role IN<foreach item="role" collection="roles" open="(" separator="," close=")">#{role}</foreach></if></where></select>
2、常用标签
1)<if> 标签
a)用途:条件判断,满足条件时包含 SQL 片段。
b)示例
<select id="findUser" resultType="User">SELECT * FROM userWHERE 1=1<if test="name != null">AND name = #{name}</if></select>
2)<where> 标签
a)用途:自动添加 WHERE 关键字,并去除首条多余的 AND/OR。
b)示例
<select id="selectByStudent" resultMap="BaseResultMap" parameterType="com.xxx.entity.Student">select<include refid="Base_Column_List" />from student<where><if test="name != null and name !=''">and name like concat('%', #{name}, '%')</if><if test="sex != null">and sex=#{sex}</if></where></select>
说明:以上SQL中,当条件都不满足时:此时 SQL 中应该要不能有 where , 否则导致出错。当 if 有条件满足时:SQL 中需要有 where, 且第一个成立的 if 标签下的 and | or 等要去掉,这时候,我们可以使用 where 标签。
3)<set> 标签
a)用途:主要用于SQL的UPDATE命令中,自动添加 SET 关键字,并去除末尾多余的逗号。
b)示例:
<update id="updateUser">UPDATE user<set><if test="name != null">name = #{name},</if><if test="age != null">age = #{age},</if></set>WHERE id = #{id}</update>
4)<foreach> 标签
a)用途:遍历集合(如 IN 查询、批量插入)。
b)该标签的属性:
- collection:集合参数名。- item:遍历元素的变量名。- open/close:包裹结果的前缀/后缀。- separator:元素间的分隔符。
c)示例:
<!-- IN 查询 -->SELECT * FROM user WHERE id IN<foreach item="id" collection="ids" open="(" separator="," close=")">#{id}</foreach><!-- 批量插入 -->INSERT INTO user (name) VALUES<foreach item="user" collection="list" separator=",">(#{user.name})</foreach>
注意:在使用标签时,最好在标签前加上标签,判断列表是否为null或者有数据,如果列表没数据,不加标签直接使用标签会报错。第一个查询SQL的动态SQL建议写法:
SELECT * FROM user
<if test = "ids != null and ids.size > 0">WHERE id IN
<foreach item="id" collection="ids" open="(" separator="," close=")">#{id}
</foreach>
</if>
5)<choose>/<when>/<otherwise> 标签
a)用途:多条件分支(功能类似于switch-case)。
b)示例:
<select id="findUser" resultType="User">SELECT * FROM user<where><choose><when test="name != null">AND name = #{name}</when><when test="email != null">AND email = #{email}</when><otherwise>AND is_active = 1</otherwise></choose></where></select>
6)<trim> 标签
a)用途:自定义字符串修剪(可替代 标签 或 标签)。
b)属性:
- prefix:添加前缀。- prefixOverrides:去除首部匹配的字符。- suffix:添加后缀。- suffixOverrides:去除尾部匹配的字符。
c)示例:
<!-- 替代 <where> --><trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="name != null and name != ``">
AND name = #{name}
</if></trim><!-- 替代 <set> --><trim prefix="SET" suffixOverrides=","><if test="name != null">name = #{name},</if></trim>
7)<bind> 标签
a)用途:创建变量并绑定到上下文,用于复杂表达式或重复逻辑。
b)示例:
<select id="searchUser"><bind name="pattern" value="'%' + keyword + '%'" /> <!-- 拼接模糊查询参数 -->SELECT * FROM userWHERE name LIKE #{pattern}</select>
欢迎关注工 众号:ItBeeCoder,查看更多高质量技术文章,发送“后端”获取资料
四、使用注意事项
1)OGNL表达式中:test 属性中使用的表达式语言,支持复杂逻辑,例如:==, !=, &&, || 等操作。例如:
<if test="name != null and name != ''"> <!-- 同时检查非空和非空字符串 -->
2)参数处理:
- mapper接口中抽象方法的集合参数需通过 @Param 命名
List<User> findUsersByIds(@Param("ids") List<Integer> ids);
- 空值检查需显式处理(如
test="name != null and name != ''")。
3)动态 SQL 性能:避免写过度复杂的动态SQL,过度复杂的SQL可能影响数据库执行计划,导致查询性能差。
4)动态表名/列名不建议使用 ${},建议使用#{},以防止 SQL 注入。
5)在Springboot搭配使用Mybatis时,为了能将Mapper接口上加了@Mapper或@Dao的Bean注入到spring容器中,需要在启动类中添加@MapperScan注解,@MapperScan注解中的包路径名称为mapper接口的路径。如下所示:
@SpringBootApplication@MapperScan("com.example.mapper")public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);// 其它业务代码}}
欢迎关注工 众号:ItBeeCoder,查看更多高质量技术文章,发送“后端”获取资料
五、一些最佳实践
1、在Mybatis的XML文件中对于某些频繁用到的SQL,为了避免重复写以及重复写导致的出错,可以引用某个常用的SQL,如下即为引用SQL的做法:
<sql id="all">
select * from user
</sql><select id="selectUserByUid" resultType="user">
<include refid="all"/>
where uid = #{uid}
</select><select id="selectIf" resultType="user">
<include refid="all"/>
<where>
<if test="username != null">
username = #{username}
</if>
</where>
</select>
2、判断list集合是否包含指定数据
<if test="list.contains('0')">
#{逻辑}
</if>
3、XML的SQL中比较符号的写法
gt 对应 >
gte 对应 >=
lt 对应 <(会报错 相关联的 "test" 属性值不能包含 '<' 字符)
lte 对应 <=(会报错 相关联的 "test" 属性值不能包含 '<' 字符)
<![CDATA[ sql 语句 ]]>
<![CDATA[ >= ]]>
4、MyBatis的XML中使用内部类的方式
内部类需要使用$符号连接,而不是点.,以下为正确写法:
com.xxx.model.SMSESBResult$ReceiveResult$ResultInfo
六、写在最后的话
总之,MyBatis的动态SQL功能允许开发者根据不同条件灵活构建SQL语句,避免手动拼接字符串,另外,常用查询列和查询SQL还可以借助动态SQL实现复用,提高XML中SQL代码的可维护性和安全性。
欢迎关注工 众号:ItBeeCoder,查看更多高质量技术文章,发送“后端”获取资料
又到了金三银四求职季,我整理了一些互联网大厂的面试题,有需要的可关注工 众号:ItBeeCoder,发送“后端”获取


相关文章:
MyBatis:动态SQL高级标签使用方法指南
一、引言 目前互联网大厂在搭建后端Java服务时,常使用Springboot搭配Mybatis/Mybatis-plus的框架。Mybatis/Mybatis-plus之所以能成为当前国内主流的持久层框架,与其本身的优点有关:支持定制动态 SQL、存储过程及高级映射,简化数…...
使用grafana v11 建立k线(蜡烛图)仪表板
先看实现的结果 沪铜主力合约 2025-02-12 的1分钟k线图 功能介绍: 左上角支持切换主力合约,日期,实现动态加载数据. 项目背景: 我想通过前端展示期货指定品种某1天的1分钟k线,类似tqsdk 的web_gui 生成图形化界面— TianQin Python SDK 3.7.8 文档 项目架构: 后端: fastap…...
ubuntu 安装 Redis
一、下载 Redis 压缩包,wget http://download.redis.io/releases/redis-5.0.14.tar.gz 也可以去官网下载别的版本 https://redis.io 二、解压文件,tar -zxvf redis-5.0.14.tar.gz 三、编译安装(使用压缩包的方式需要编译安装)&…...
利用docker-compose一键创建并启动所有容器
简介 在开发复杂的分布式应用时,通常需要同时运行多个服务(如数据库、缓存、Web 应用等)。Docker Compose 提供了一种简便的方式来定义和运行多容器 Docker 应用程序。通过一个 docker-compose.yml 文件,您可以配置应用程序的服务…...
mysql开启gtid并配置主从
默认主从都开启了bin log. 1.主从都在/etc/my.cnf中加入并重启服务 gtid_mode ON enforce_gtid_consistency ON 2.在主库创建用户并授权 create user slave identified with mysql_native_password by 123456 mysql>GRANT REPLICATION SLAVE ON *.* to slave% identified…...
redis sentinel模式 与 redis 分片集群 配置
Redis 最低为5.0版本,以下为6.2.6版本信息。 模式 高可用性 数据分片 部署复杂度 适用场景 Sentinel 模式 高 无 中等 中小规模,需要高可用性 集群模式 高 支持 复杂 大规模,需要高…...
2025最新在GitHub上搭建个人图床,保姆级图文教程,实现图片高效管理
文章目录 🌍一. 图床❄️1.什么是图床❄️2.图床能解决什么问题? 🌍二. 在github上面创建图床🌍三. PicGo❄️1. PicGo介绍❄️ 2. 下载与安装❄️3. 配置图床 ❄️3.错误解决问题1问题2问题3问题4 🌍 四. Typora❄️…...
Web后端 - Maven管理工具
一 Maven简单介绍 Maven是apache旗下的一个开源项目,是一款用于管理和构建java项目的工具。 Maven的作用 二 Maven 安装配置 依赖配置 依赖传递 依赖范围 生命周期 注意事项:在同一套生命周期中,当运行后面的阶段时,前面的阶段都…...
【python语言应用】最新全流程Python编程、机器学习与深度学习实践技术应用(帮助你快速了解和入门 Python)
近年来,人工智能领域的飞速发展极大地改变了各个行业的面貌。当前最新的技术动态,如大型语言模型和深度学习技术的发展,展示了深度学习和机器学习技术的强大潜力,成为推动创新和提升竞争力的关键。特别是PyTorch,凭借其…...
《探秘Windows 11驱动开发:从入门到实战》
《探秘Windows 11驱动开发:从入门到实战》 驱动开发初印象 在 Windows 11 这个充满活力与创新的操作系统世界里,驱动程序犹如幕后英雄,默默发挥着无可替代的关键作用。它是连接操作系统与硬件设备的桥梁,操作系统下达的指令,如播放音乐、读取硬盘数据等,都需要通过驱动…...
搭建Deepseek推理服务
概述: 本文介绍用Open webui ollama搭建一套Deepseek推理服务,可以在web页面上直接进行对话。作为体验搭建的是Deepseek 7b参数版本 首先选择一个云厂商创建一台ubuntu系统的虚拟机,带公网IP,通过shell登录虚拟机完成以下操作&…...
Golang GC 三色标记法
三色标记法 Golang GC 会使用三种颜色会对象进行标记。分别为白色、灰色和黑色。白色表示尚未被标记的对象、灰色表示已经追踪但还没标记的对象,黑色表示已经完成标记的对象。黑色表示活跃对象,不会被回收。 以下图所示,演示三色标记法的过…...
重新出发的LLM本地部署——DeepSeek加持下的Ollama+OpenWebUI快速部署
DeepSeek 这真的是太惊艳了,发布出来的模型这么能打,在线的版本使用起来也是丝滑连招,感觉效果比起之前一直用智谱 chatglm4 更好用,想着本地化部署一下。 本来以为,会和之前在开发测试 transformers 的模型和代码一样…...
【第3章:卷积神经网络(CNN)——3.5 CIFAR-10图像分类】
嘿,小伙伴们,今天咱们来聊聊一个超级酷炫的话题——卷积神经网络(CNN)及其在CIFAR-10图像分类中的应用。这不仅仅是一个技术话题,更是一场探索人工智能奥秘的旅程。准备好了吗?咱们这就发车! 一、CNN:人工智能的“千里眼” 首先,咱们得知道CNN是啥。CNN,全名Convol…...
Django后台新建管理员
在 Django 中,新建管理员用户通常涉及使用 Django 自带的命令行工具 manage.py。以下是具体步骤: 前提条件 Django 项目已创建:确保你已经创建了一个 Django 项目和应用。数据库已迁移:确保你已经运行了 python manage.py migra…...
【第12章:深度学习与伦理、隐私—12.2 数据隐私保护与差分隐私技术的实现与应用】
凌晨三点的数据中心,安全工程师老张盯着监控屏幕——某个医疗AI模型的训练日志显示,系统在保护隐私的同时竟然准确预测了罕见病的发病规律。这种看似魔法的技术背后,是一场持续了十五年的隐私保卫战。让我们掀开差分隐私的神秘面纱,看看这场革命如何重塑数据世界的游戏规则…...
索引----数据库
本博客全是来自于黑马程序员的mysql专题,我写的笔记 索引 是帮助Mysql高效获取数据的数据结构(有序) 数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,…...
【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十七节】
ISO 14229-1:2023 UDS诊断服务测试用例全解析(InputOutputControl_0x2F服务) 作者:车端域控测试工程师 更新日期:2025年02月14日 关键词:UDS协议、0x2F服务、输入输出控制、ISO 14229-1:2023、ECU测试 一、服务功能概…...
nodejs:express + js-mdict 网页查询英汉词典,能显示图片
向 DeepSeek R1 提问: 我想写一个Web 前端网页,后台用 nodejs js-mdict , 实现在线查询英语单词,并能显示图片 1. 项目结构 首先,创建一个项目目录,结构如下: mydict-app/ ├── public/ │ ├── …...
matlab汽车动力学半车垂向振动模型
1、内容简介 matlab141-半车垂向振动模型 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
HTTPS证书一年多少钱?
HTTPS证书作为保障网站数据传输安全的重要工具,成为众多网站运营者的必备选择。然而,面对市场上种类繁多的HTTPS证书,其一年费用究竟是多少,又受哪些因素影响呢? 首先,HTTPS证书通常在PinTrust这样的专业平…...
