MyBatis 动态 SQL 详解

news2024/10/22 3:58:44

1. 什么是动态 SQL?

在使用 MyBatis 进行数据库查询时,可能会遇到一些需要根据条件动态生成 SQL 语句的情况。MyBatis 提供了强大的动态 SQL 支持,通过标签和条件语句,可以让 SQL 语句根据不同的输入参数动态生成。这大大提高了代码的灵活性,避免了拼接 SQL 语句的繁琐和出错风险。

2. 动态 SQL 的常见场景

  1. 条件查询:根据不同的参数执行不同的查询条件。
  2. 批量插入或更新:动态生成多个插入或更新语句。
  3. 分页查询:根据分页参数动态限制查询范围。
  4. 可选查询条件:根据用户输入,动态生成 SQL。

3. 动态 SQL 的常用标签

MyBatis 提供了一些标签来支持动态 SQL,包括:

  1. <if>:判断条件,生成部分 SQL。
  2. <choose>:类似于 switch 语句,在多个条件之间选择。
  3. <where>:自动添加 WHERE,并处理多余的 AND 或 OR
  4. <trim>:在 SQL 前后添加或去除多余的字符(如逗号、AND)。
  5. <foreach>:用于循环遍历集合,生成动态 SQL。
  6. <set>:在更新语句中处理动态的 SET 字段。

4. 常见动态 SQL 用法示例

4.1 使用 <if> 标签

假设我们有一个查询用户的需求,根据不同的查询条件(username 和 age)来生成查询 SQL:

Mapper XML 文件:

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

生成 SQL 示例:

  • 当传入 username="Alice" 时:
    SELECT * FROM users WHERE username = 'Alice';
    
  • 当传入 username="Alice", age=25 时:
    SELECT * FROM users WHERE username = 'Alice' AND age = 25;
    

4.2 使用 <choose> 标签

<choose> 标签类似于 Java 中的 switch,可以根据条件选择执行某段 SQL。

<select id="selectUserByStatus" parameterType="map" resultType="User">
    SELECT * FROM users
    <where>
        <choose>
            <when test="status == 'active'">
                status = 'active'
            </when>
            <when test="status == 'inactive'">
                status = 'inactive'
            </when>
            <otherwise>
                1 = 1
            </otherwise>
        </choose>
    </where>
</select>

SQL 示例:

  • 当 status='active' 时:
    SELECT * FROM users WHERE status = 'active';
    
  • 当没有传入 status 时:
    SELECT * FROM users WHERE 1 = 1;
    

4.3 使用 <foreach> 标签

<foreach> 常用于处理集合类型参数,比如批量插入或查询。

<select id="selectUsersByIds" parameterType="list" resultType="User">
    SELECT * FROM users WHERE id IN
    <foreach item="id" index="index" collection="list" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

Java 调用:

List<Integer> ids = Arrays.asList(1, 2, 3);
userMapper.selectUsersByIds(ids);

生成 SQL:

SELECT * FROM users WHERE id IN (1, 2, 3);


4.4 使用 <where> 标签

<where> 会自动处理 SQL 中多余的 AND 或 OR,避免语法错误。

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

  • 当只传入 age=25 时:
    SELECT * FROM users WHERE age = 25;
    

4.5 使用 <set> 标签

在更新语句中,如果只有部分字段需要更新,使用 <set> 标签可以避免多余的逗号。

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

SQL 示例:

  • 当传入 username="Alice" 和 status="active" 时:
    UPDATE users SET username = 'Alice', status = 'active' WHERE id = ?;
    

5. 动态 SQL 的最佳实践

  1. 合理使用动态标签:不要将过多逻辑放在 XML 文件中,复杂逻辑可以放在 Java 代码中处理。
  2. 避免 SQL 注入:使用 MyBatis 提供的参数占位符(#{})来避免拼接 SQL。
  3. 适当分解 SQL 语句:对于复杂的 SQL,可以拆分成多个小查询,减少 XML 文件的复杂度。
  4. 使用日志调试 SQL:开启 MyBatis 的日志功能,查看生成的 SQL 是否符合预期。

6. 结论

MyBatis 动态 SQL 提供了非常强大的功能,可以根据不同的业务需求生成灵活的 SQL 语句。通过 <if><choose><foreach> 等标签,我们可以在 XML 中轻松实现复杂的查询逻辑。在使用过程中,我们需要注意 SQL 的可读性和维护性,避免过多复杂逻辑堆积在 XML 文件中。

掌握 MyBatis 的动态 SQL,可以让你的代码更具弹性,适应不同的业务场景。希望这篇文章能帮助你更好地理解和使用 MyBatis 的动态 SQL 功能。

希望你喜欢这篇关于JMyBatis 动态 SQL 详解的博客文章!请各位点赞和收藏加关注一键三连吧。祝三连的帅哥美女们今年都能暴富。如果有更多问题,欢迎随时提问。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

外包干了30年,人都快要废了。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入南京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…

如何做软件系统的维护成本估算?

一、人员成本 维护工程师 确定维护工程师的数量和技能级别。例如&#xff0c;可能需要 2 名中级维护工程师&#xff0c;月薪 10000 元左右。计算每月的人员成本为 2 10000 20000 元。 技术支持人员 技术支持人员负责解答用户的问题和处理紧急情况。假设需要 1 名技术支持人员…

django5入门【03】新建一个hello界面

注意 ⭐前提&#xff1a;将上节的项目导入到pycharm中操作步骤总结&#xff1a; 1、HelloDjango/HelloDjango目录下&#xff0c;新建一个views.py 2、HelloDjango/HelloDjango/urls.py 文件中&#xff0c;配置url路由信息 3、新建终端&#xff0c;执行运行命令python manag…

Noteexpress在已有作者名字时怎么只标注年份

如图 需要除掉重复的人名 达到如下只出现年份的效果 方法&#xff1a; 打开 编辑引文 然后&#xff0c;选中文献&#xff0c;并勾选“不显示作者名” 按确定即可。

js.杨辉三角和分发饼干

1&#xff0c;链接&#xff1a;118. 杨辉三角 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows …

PostgreSQL的学习心得和知识总结(一百五十五)|[performance]优化期间将 WHERE 子句中的 IN VALUES 替换为 ANY

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

二叉树遍历(前序、中序、后续)

目录 什么是二叉树二叉树遍历以递归创建树的角度看前、中、后序遍历前序遍历中序遍历后序遍历 栈来实现前、中、后序遍历栈的实现栈操作进行前序、中序遍历代码实现中序遍历和先序遍历栈操作进行后序遍历 什么是二叉树 树&#xff1a;树的根节点没有前驱&#xff0c;除根节点以…

Spring声明式事务管理:深入探索XML配置方式

前言 Spring的事务管理&#xff0c;无论是基于xml还是注解实现&#xff0c;本质上还是实现数据库的事务管理机制&#xff0c;因此要注意发送SQL的连接是否为同一个&#xff0c;这是实现声明式事务的关键。 以下案例和实现基于SSM整合框架完成&#xff0c;不知道如何整合SSM&…

CTFHUB技能树之文件上传——无验证

开启靶场&#xff0c;打开链接&#xff1a; 直接上传一句话木马&#xff1a; <?php eval($_POST[pass]);?> 成功提交并显示了上传的文件的路径 访问一下该文件触发一句话木马&#xff1a; 看到一片空白是正常的&#xff0c;因为没有写什么函数&#xff0c;比如&#x…

FineReport 计算同比增长

1、数据库查询 SELECTt1.年,t1.月,t1.总金额 AS 同期金额,t1.仓库名称,t2.总金额 AS 上期金额 FROMtest t1LEFT JOIN test t2 ON ( t1.年 t2.年 1 ) AND t1.月 t2.月 AND t1.仓库名称 t2.仓库名称2、配置字段 月份字段加后缀 月 数据列加后缀 计算同比增长率 if(LEN(B3)0 …

移动零---双指针法

目录 一&#xff1a;题目 二:算法原理讲解 三&#xff1a;代码编写 一&#xff1a;题目 题目链接&#xff1a;https://leetcode.cn/problems/move-zeroes/description/ 二:算法原理讲解 三&#xff1a;代码编写 void moveZeroes2(vector<int>& nums) {for (int d…

数据轻松上云——Mbox边缘计算网关

随着工业4.0时代的到来&#xff0c;工厂数字化转型已成为提升生产效率、优化资源配置、增强企业竞争力的关键。我们凭借其先进的边缘计算网关与云平台技术&#xff0c;为工厂提供了高效、稳定的数据采集与上云解决方案。本文将为您介绍Mbox边缘计算网关如何配合明达云平台&…

基于Java语言的培训平台+学习平台+在线学习培训系统+教育平台+教育学习系统+课程学习平台

简述 企业培训平台企业考试系统培训平台考试系统企业大学企业视频网站视频学习平台 介绍 企业培训平台支持企业培训考试全流程&#xff0c;在线学习、在线考试&#xff0c;成熟的企业培训考试解决方案&#xff0c;充分满足企业培训需求。 独立部署&#xff0c;仅内部员工登录…

JAVA高级--常用类(九)

JAVA高级–常用类 观看b站尚硅谷视频做的笔记 1、字符串相关的类 1.1 String 的使用 String 的特性&#xff1a; String 类&#xff1a;代表字符串。Java 程序中的所有字符串字面值&#xff08;如 “abc”&#xff09;都作为此类的实例实现。 String 是一个 final 类&#…

ESP8266 模块介绍—AT指令学习 笔记

零、简介 感谢百文网韦东山 老师对ESP8266模块的讲解 笔记在CSDN也有文章备份 大家可以在我的gitee仓库 中下载笔记源文件、ESP8266资料等 笔记源文件可以在Notion中导入 一、ESP8266-01S模块详细介绍 1. 名字的由来 ESP8266 是方形的主控芯片旁边的长方形是一个Flash-0…

IO编程——消息队列

题目&#xff1a; 代码实现&#xff1a; #include <myhead.h> //正文大小 #define MSGSZ (sizeof(struct msgbuf)-sizeof(long)) //定义要发送的消息类型 struct msgbuf{long msgtype; //消息类型char mtext[1024]; //消息正文 };int main(int argc, const char *ar…

全面升级:亚马逊测评环境方案的最新趋势与实践

在亚马逊测评领域深耕多年&#xff0c;见证了无数环境方案的更迭与演变&#xff0c;每一次变化都体现了国人不畏艰难、勇于创新的精神。面对平台的政策调整&#xff0c;总能找到相应的对策。那么&#xff0c;当前是否存在一套相对稳定且高效的技术方案呢&#xff1f;答案是肯定…

【计网】从零开始理解TCP协议 --- 拥塞控制机制,延迟应答机制,捎带应答,面向字节流

时间就是性命。 无端的空耗别人的时间&#xff0c; 其实是无异于谋财害命的。 --- 鲁迅 --- 从零开始理解TCP协议 1 拥塞控制2 延迟应答3 捎带应答4 面向字节流5 TCP异常情况TCP小结 1 拥塞控制 尽管TCP拥有滑动窗口这一高效的数据传输机制&#xff0c;能够确保在对方接收…

基于卷积神经网络的蔬菜识别系统,resnet50,mobilenet模型【pytorch框架+python源码】

更多目标检测和图像分类识别项目可看我主页其他文章 功能演示&#xff1a; 基于卷积神经网络的蔬菜识别系统&#xff0c;resnet50&#xff0c;mobilenet【pytorch框架&#xff0c;python&#xff0c;tkinter】_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷积神…

关于vue3中如何实现多个v-model的自定义组件

实现自定义组件<User v-model"userInfo" v-model:gender"gender"></User> User组件中更改数据可以同步更改父组件中的数据&#xff1a; 1 父组件&#xff1a; <User v-model"userInfo" v-model:gender"gender">&…