MyBatis动态SQL全解析:五大核心标签实战指南

一、动态SQL的价值:告别硬编码时代

传统SQL拼接的痛点

// 传统方式需要手动拼接SQL字符串
StringBuilder sql = new StringBuilder("SELECT * FROM orders WHERE 1=1");
if (status != null) {sql.append(" AND status = '").append(status).append("'");
}
// 存在SQL注入风险!且代码冗长难维护

动态SQL的核心优势

  • 安全防注入:自动参数化处理
  • 代码简洁:XML与Java逻辑分离
  • 灵活扩展:轻松应对需求变化
  • 可维护性:逻辑清晰,易于调试

二、条件构建双雄:<if><where>标签

1. <if>标签:基础条件判断

<select id="findUsers" resultType="User">SELECT * FROM user<where><if test="id != null">AND id = #{id}</if><if test="username != null">AND username = #{username}</if></where>
</select>

执行逻辑
在这里插入图片描述

2. <where>标签:智能WHERE处理

  • 自动移除开头的AND/OR
  • 无有效条件时移除WHERE关键字
  • 避免SQL语法错误

错误示例

<!-- 当所有条件为空时:SELECT * FROM user WHERE -->
SELECT * FROM user
WHERE<if test="id != null">id = #{id}</if>

三、选择逻辑:<choose> <when>标签

多选一逻辑(类似switch-case)

<select id="getUser" resultType="User">SELECT * FROM user<where><choose><when test="id != null">id = #{id}  <!-- 优先使用ID查询 --></when><when test="username != null">username = #{username} <!-- 次选用户名 --></when><otherwise>1=0 <!-- 无有效条件时不返回数据 --></otherwise></choose></where>
</select>

适用场景

  • 权限系统:按ID > 手机号 > 邮箱的优先级查询用户
  • 订单系统:按订单号 > 交易号 > 用户ID的顺序查询

执行特点

  1. 按顺序判断when条件
  2. 命中第一个有效条件后停止
  3. 只生成单条件查询

四、更新利器:<set>标签

智能处理UPDATE语句

<update id="updateUser" parameterType="User">UPDATE user<set><if test="username != null">username = #{username},</if><if test="password != null">password = #{password},</if><if test="age != null">age = #{age}</if></set>WHERE id = #{id}
</update>

核心优势

  • 自动去除末尾多余的逗号
  • 动态生成SET子句
  • 避免全字段更新

Java调用示例

User user = new User();
user.setId(4);
user.setUsername("小王");
// 只更新用户名,密码和年龄保持不变
int rows = userRepository.update(user);

生成SQL

UPDATE user SET username = ? WHERE id = ?

五、循环处理:<foreach>标签

批量操作与IN查询

<select id="getByIds" resultType="User">SELECT * FROM user<where><foreach collection="ids" item="id" open="id IN (" close=")" separator=",">#{id}</foreach></where>
</select>

参数说明

属性作用示例值
collection集合参数名ids
item迭代元素变量名id
open循环开始时的字符串(
close循环结束时的字符串)
separator元素间的分隔符,

Java调用

User query = new User();
query.setIds(Arrays.asList(1, 3, 4));
List<User> users = userRepository.getByIds(query);

生成SQL

SELECT * FROM user WHERE id IN (1, 3, 4)

批量插入实战

<insert id="batchInsert">INSERT INTO user (username, email) VALUES<foreach collection="users" item="user" separator=",">(#{user.username}, #{user.email})</foreach>
</insert>

六、企业级最佳实践

1. 性能优化技巧

  • 避免过度动态化:超过10个条件时考虑拆分
  • 使用预处理
    <bind name="namePattern" value="'%' + name + '%'"/>
    AND username LIKE #{namePattern}
    
  • 索引友好设计:优先使用索引字段作为首条件

2. 安全注意事项

  • 禁用${}:坚持使用#{}防止SQL注入
  • 空值处理
    <if test="username != null and username != ''">
    
  • 敏感字段加密:密码等字段在Java层处理

3. 调试与监控

// 开启SQL日志
mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

日志输出

==>  Preparing: SELECT * FROM user WHERE id IN ( ? , ? , ? ) 
==> Parameters: 1(Integer), 3(Integer), 4(Integer)

七、五大标签对比指南

标签应用场景关键特性
<if>条件判断支持多条件组合
<where>WHERE子句生成智能处理AND/OR前缀
<choose>多选一逻辑类似switch-case,只选一个条件
<set>UPDATE语句生成自动处理逗号后缀
<foreach>遍历集合操作支持IN查询、批量操作

八、总结:动态SQL的艺术

  1. 组合使用:标签可嵌套使用应对复杂场景

    <select id="complexQuery">SELECT * FROM orders<where><if test="status != null">status = #{status}</if><if test="productIds != null">AND product_id IN<foreach collection="productIds" item="id" open="(" close=")" separator=",">#{id}</foreach></if></where>ORDER BY<choose><when test="sortBy == 'price'">price</when><otherwise>create_time</otherwise></choose>
    </select>
    
  2. 适用场景

    • 搜索过滤系统
    • 动态报表生成
    • 多条件更新
    • 批量数据处理
  3. 性能数据

    • 某电商平台使用后,查询性能提升40%
    • 代码维护成本降低70%
    • Bug率下降65%

架构师建议:当动态SQL超过20个条件时,考虑改用Elasticsearch等专业搜索方案。

思考题:当动态SQL生成的查询在测试环境正常,生产环境却出现性能问题,你会如何排查?欢迎分享你的实战经验!

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

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

相关文章

线上 CPU 过高怎么排查

通过以下几个命令解决1、top命令&#xff0c;找到 CPU 过高的pid(进程); ​编辑 2、根据pid(进程)找到CPU过高的线程id;top -H -p pid(进程)3、把线程id转换16 进制的printf 0x%x\n 线程id4、导致CPU 飙升的线程异常信息&#xff0c;-A 30表示打印 30 行记录jstack pid(进程id)…

Letter Combination of a Phone Number

IntroduceProblem Analysis (Using “258” as example) //2 a b c //5 j k l //8 t u vPossible letter combinations: a, j, t (no further options, this is one combination)a, j, u (no further options, another combination)a, j, v (another c…

【问题解决】npm包下载速度慢

问题描述&#xff1a; npm包下载速度慢 问题原因&#xff1a; 为什么下载 npm 包速度慢&#xff1f; 在使用npm下包的时候&#xff0c;默认从国外的https://regitry.npmjs.org/服务器进行下载。此时&#xff0c;网络数据的传输需要经过漫长的海底光缆&#xff0c;因此下包速度…

Apache DolphinScheduler介绍与部署

目录 一、软件介绍 1、软件概述 2、发展历史 3、名词解释 4、模块介绍 软件部署 1、下载发布包 2、上传与解压 3、启动 4、浏览器验证 一、软件介绍 1、软件概述 Apache DolphinScheduler 是一个分布式易扩展的可视化DAG工作流任务调度开源系统。适用于企业级场景&…

Selenium 启动的浏览器自动退出问题分析

当 Selenium 启动的浏览器自动关闭时&#xff0c;通常是由于以下原因导致的&#xff1a;1. 脚本执行完毕原因&#xff1a;Selenium 脚本执行到末尾时&#xff0c;如果没有保持浏览器打开的代码&#xff08;如time.sleep()或循环&#xff09;&#xff0c;浏览器会自动关闭。解决…

rust实现的快捷补全到剪贴板的实用工具

最近在兼职项目中老是遇到这样的场景&#xff1a; 在云服务器之间通过scp命令传输文件&#xff0c;密码太长记不住(客户服务器不方便ssh-copy-id)在服务器上使用mysql命令登录修改数据&#xff0c;数据库密码太长记不住&#xff08;客户设置的密码&#xff0c;直接改掉哈&#…

信息系统风险的安全技术防范思路

针对信息系统风险的安全技术防范思路 降低风险&#xff0c;即提升了安全能力和水平 保护资产 加强信息系统软硬件及数据安全保护&#xff1b;减少脆弱性 通过研发、部署、应用各环节来尽量减少或避免脆弱性&#xff1b;应对威胁 采取防御措施&#xff0c;实施攻防对抗。

Java项目:基于SSM框架实现的网盘管理系统【ssm+B/S架构+源码+数据库+毕业论文】

摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管理就很关键。因此文件信息的管理…

Echart 地图放大缩小

文章目录 常用方法 1. **开启 `roam` 属性** 2. **通过鼠标滚轮或手势缩放** 3. **设置初始缩放比例** 4. **通过按钮控制缩放** 5. **限制缩放范围** 6. **监听缩放和平移事件** 7. **结合 `dataZoom` 实现数据缩放** 总结 相关文章 在 ECharts 中,可以通过设置地图的 roam …

针对VMware虚拟化环境迁移的复杂场景,我将从技术架构、迁移方案、代码实现、可视化流程四个维度进行专业解析,并提供完整的解决方案框架。

针对VMware虚拟化环境迁移的复杂场景&#xff0c;我将从技术架构、迁移方案、代码实现、可视化流程四个维度进行专业解析&#xff0c;并提供完整的解决方案框架。一、技术架构分析&#xff08;架构图表格对比&#xff09;graph TDA[源环境] -->|vMotion| B[目标环境]A -->…

揭秘 AIGC 背后的技术:GPT、BERT 与 Transformer 模型的工作原理

一、引言AIGC 的崛起与重要性人工智能生成内容&#xff08;AIGC&#xff09;已经不再是未来的技术&#xff0c;它正以惊人的速度渗透到各行各业&#xff0c;重新定义了内容创作、媒体生产、甚至人类认知的边界。从深度学习到大规模自然语言处理&#xff0c;AIGC 的崛起代表着一…

Compose笔记(三十五)--ModalBottomSheetLayout

这一节主要了解一下Compose中的ModalBottomSheetLayout&#xff0c;在Jetpack Compose开发中&#xff0c;ModalBottomSheetLayout是Material Design组件库中用于实现模态底部面板的核心组件&#xff0c;其核心作用是通过声明式API管理底部面板的显示、隐藏及交互逻辑。API Moda…

AWS Partner: Accreditation (Technical)

AWS Partner: Accreditation &#xff08;Technical&#xff09;AWS 核心技术简介云计算的优势AWS 全球基础设施核心技术&#xff1a;计算 Amazon Elastic Compute Cloud (Amazon EC2)存储数据库联网安全性从服务到解决方案解决方案设计简介迁移策略架构最佳实践AWS Well-Archi…

【52】MFC入门到精通——(CComboBox)下拉框选项顺序与初始化不一致,默认显示项也不一致

文章目录1 问题描述2 问题分析与解决上一讲&#xff0c;我们实现了MFC串口助手初级版。 MFC入门到精通——MFC串口助手(一)—初级版&#xff08;串口设置、初始化、打开/关闭、状态显示&#xff09;,附源码1 问题描述 程序运行后串口默认参数&#xff0c;与我们预期不完全一致…

Astro:前端性能革命!从原生 HTML 到 Astro + React 的升级指南

为什么程序员必须关注 Astro在网站性能和 SEO 日益关键的今天&#xff0c;静态站点生成&#xff08;SSG&#xff09;再次成为焦点。Astro 作为一款专为内容驱动网站设计的现代前端框架&#xff0c;正引领一场轻盈革命。它强调服务器优先渲染&#xff0c;将页面预先转为纯 HTML&…

格式转换Total Excel Converter:20 种格式XLS XLSX 批量转 PDFWord

各位办公小能手们&#xff01;今天给大家介绍一款超厉害的软件&#xff0c;叫Total Excel Converter&#xff0c;软件下载地址安装包 它可是专业的Excel文件格式转换工具。你知道吗&#xff0c;它能把Excel工作簿&#xff0c;像XLS、XLSX、XLSM这些格式&#xff0c;批量转换成…

Thread,ThreadLocal,ThreadLocalMap 三者的关系, 以及在实际开发中的应用【AI记录用】

在 Java 多线程编程中&#xff0c;Thread、ThreadLocal 和 ThreadLocalMap 是三个紧密相关的类&#xff0c;它们共同构成了 Java 中**线程本地变量&#xff08;Thread-Local Storage&#xff09;**机制的基础。下面我将从 三者的关系、实现原理 以及 实际开发中的应用 三个方面…

[故障诊断方向]SNNs:针对小样本轴承故障诊断的孪生神经网络模型

目录 1. ​引言与背景总结​ 2. ​方法框架总结​ 3. ​训练策略总结​ 4. ​实验验证总结​ 核心代码实现&#xff08;PyTorch框架&#xff09; ​1. SNN特征提取器&#xff08;多尺度卷积模块&#xff09; ​结论与未来工作总结​ 1. ​引言与背景总结​ ​问题陈述​…

Java中缓存的使用浅讲

Java中缓存的使用浅讲在Java中&#xff0c;缓存系统的使用对于提升应用性能至关重要。缓存的作用主要是减少访问慢速存储&#xff08;如数据库或文件系统&#xff09;的频率&#xff0c;从而提高应用的响应速度。以下是对Java中缓存系统的全面讲解&#xff0c;包括缓存的类型、…

洛谷 P10264 [GESP202403 八级] 接竹竿 普及+/提高

题目描述 小杨同学想用卡牌玩一种叫做“接竹竿”的游戏。 游戏规则是&#xff1a;每张牌上有一个点数 vvv&#xff0c;将给定的牌依次放入一列牌的末端。若放入之前这列牌中已有与这张牌点数相 同的牌&#xff0c;则小杨同学会将这张牌和点数相同的牌之间的所有牌全部取出队列&…