当前位置: 首页 > news >正文

MyBatis动态SQL标签总结、开发手册、高阶用法(动态SQL、OGNL、批量操作、片段重用、 SQL 组合、 执行优化、嵌套查询与延迟加载)

MyBatis提供了一个非常强大的动态SQL功能,它使用了一组XML标签来帮助我们根据不同条件生成动态SQL。动态SQL的设计让开发者可以根据业务需求,灵活地构建SQL查询语句。以下是MyBatis动态SQL标签的总结。

动态SQL标签说明特点
<if>条件判断语句,用于在满足条件时生成SQL灵活、简洁,常用于简单条件的动态拼接
<choose>类似于Java中的switch-case,实现多分支选择避免多个<if>嵌套,代码更清晰
<when><choose>中的条件分支,与<otherwise>搭配使用逻辑清晰,适合多条件判断
<otherwise><choose>中的默认分支,相当于else用于定义默认情况的SQL
<where>自动处理WHERE子句的拼接,避免前后多余的ANDOR语法整洁,自动优化条件拼接
<set>自动处理UPDATE语句中的SET子句,避免最后的逗号问题便于更新操作时的动态SQL生成
<trim>自定义去除SQL前后多余的字符,通常用于WHERESET子句灵活,可以指定前后缀和修饰符
<foreach>循环构造SQL片段,适合用于IN查询或批量插入高效处理批量操作
<bind>动态绑定变量可以通过OGNL表达式为SQL传递动态变量

各标签的详细分析及特点

  1. <if> 标签

    • 用法:根据条件是否满足来决定是否生成SQL片段。
    • 特点:简洁且灵活,可以在SQL语句中动态插入条件,是最常用的动态标签之一。
    <select id="findUserByCondition" parameterType="User">SELECT * FROM users<where><if test="username != null">AND username = #{username}</if><if test="age != null">AND age = #{age}</if></where>
    </select>
    
    • 优点:适用于简单条件的判断和拼接,便于根据参数的存在与否动态生成不同的SQL。
  2. <choose> 标签

    • 用法:实现类似switch-case的逻辑,多条件下选择生成SQL片段。
    • 特点:避免了多个<if>嵌套,代码更易读,逻辑更清晰。
    <choose><when test="username != null">AND username = #{username}</when><when test="age != null">AND age = #{age}</when><otherwise>AND status = 'active'</otherwise>
    </choose>
    
    • 优点:对于多个条件判断且互斥的情况下,<choose>比多个<if>更高效和清晰。
  3. <where> 标签

    • 用法:用于SQL的WHERE子句,自动处理前后多余的ANDOR等。
    • 特点:通过自动处理逻辑,避免手动控制拼接,提升代码整洁度。
    <where><if test="username != null">username = #{username}</if><if test="age != null">AND age = #{age}</if>
    </where>
    
    • 优点:自动优化SQL结构,特别适合用于动态条件的查询。
  4. <set> 标签

    • 用法:处理UPDATE语句中的SET子句,避免拼接时多余的逗号。
    • 特点:自动去掉最后多余的逗号,使UPDATE操作更为高效。
    <update id="updateUser">UPDATE users<set><if test="username != null">username = #{username},</if><if test="age != null">age = #{age},</if></set>
    </update>
    
    • 优点:处理更新操作时,代码简洁,并且自动去除末尾的多余标点。
  5. <foreach> 标签

    • 用法:用于在SQL中处理集合,如IN查询、批量插入等。
    • 特点:支持集合循环操作,适合大批量的SQL语句生成。
    <select id="findUsersByIds">SELECT * FROM users WHERE id IN<foreach item="id" collection="list" open="(" separator="," close=")">#{id}</foreach>
    </select>
    
    • 优点:极大简化了批量操作的SQL构造,减少代码冗余,提高效率。
  6. <trim> 标签

    • 用法:自定义去除SQL片段中的多余字符,如前后缀。
    • 特点:提供了对SQL结构的高度自定义控制,便于精细化管理SQL。
    <trim prefix="WHERE" prefixOverrides="AND | OR"><if test="username != null">AND username = #{username}</if><if test="age != null">AND age = #{age}</if>
    </trim>
    
    • 优点:灵活地控制SQL片段拼接,尤其在多条件拼接时避免SQL错误。
  7. <bind> 标签

    • 用法:用于绑定OGNL表达式,动态生成SQL变量。
    • 特点:能够将动态变量引入SQL,使得SQL更灵活。
    <bind name="pattern" value="'%' + username + '%'"/>
    SELECT * FROM users WHERE username LIKE #{pattern}
    
    • 优点:适合于需要灵活绑定变量的场景,使查询条件更加多样化。

案例:通过MyBatis实现动态查询

以下是一个实际应用中的场景,通过综合使用多种MyBatis动态SQL标签,实现用户的动态查询。

<select id="findUsersByCondition" parameterType="map">SELECT * FROM users<where><if test="username != null">username = #{username}</if><if test="age != null">AND age = #{age}</if><if test="status != null">AND status = #{status}</if><if test="idList != null">AND id IN<foreach collection="idList" item="id" open="(" separator="," close=")">#{id}</foreach></if></where>
</select>

高级用法

MyBatis 的动态 SQL 基本标签虽然覆盖了大部分常见场景,但在更复杂的业务场景下,还有一些高级用法和技巧可以用来提升代码的灵活性和性能。以下是一些常见的高级用法:

1. 动态生成复杂的SQL查询

在某些情况下,可能需要根据复杂的业务逻辑生成 SQL。这时可以利用 MyBatis 标签的组合和嵌套来处理。通过 <choose><if><foreach> 的组合,可以实现复杂的 SQL 查询。

案例:多条件动态查询带分页

<select id="findUsersByConditions" parameterType="map" resultType="User">SELECT * FROM users<where><if test="username != null and username != ''">username = #{username}</if><if test="email != null and email != ''">AND email = #{email}</if><if test="age != null">AND age = #{age}</if><if test="roles != null">AND role IN <foreach collection="roles" item="role" open="(" separator="," close=")">#{role}</foreach></if></where>ORDER BY created_at DESCLIMIT #{offset}, #{limit}
</select>

2. 使用 OGNL 表达式做更复杂的条件判断

MyBatis 支持 OGNL(Object-Graph Navigation Language)表达式,使得条件判断更为灵活。你可以在 <if><bind> 标签中使用这些表达式,甚至进行复杂的逻辑运算。

案例:判断对象内部属性

<select id="findUsers" parameterType="User">SELECT * FROM users<where><if test="username != null and username.length > 3">username = #{username}</if><if test="email != null and email.contains('@')">AND email = #{email}</if></where>
</select>

3. 动态生成表名或列名

在一些动态表结构或者多表查询场景中,可能需要动态地指定表名或者列名。MyBatis 不支持直接将参数传递到表名或列名的占位符中,但可以通过 <bind> 标签动态构造 SQL 片段。

案例:动态表名

<select id="selectFromDynamicTable" parameterType="map"><bind name="dynamicTable" value="tableName"/>SELECT * FROM ${dynamicTable} WHERE id = #{id}
</select>

注意:使用 ${} 而非 #{},因为 ${} 是字符串替换,适合动态表名,而 #{} 是参数化查询,适合传递值。

4. 高级批量操作

通过 <foreach> 标签,可以在 INSERTUPDATEDELETE 中进行高级的批量操作。

案例:批量插入

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

案例:批量更新

<update id="batchUpdateUsers" parameterType="list"><foreach collection="list" item="user" separator=";">UPDATE users<set><if test="user.username != null">username = #{user.username},</if><if test="user.email != null">email = #{user.email},</if><if test="user.age != null">age = #{user.age}</if></set>WHERE id = #{user.id}</foreach>
</update>

5. 动态 SQL 片段重用

在大型系统中,可能有很多类似的 SQL 片段会被多处调用,MyBatis 提供了 SQL 片段的复用机制,可以使用 <sql> 标签定义一个可复用的 SQL 片段,再通过 <include> 标签引入。

案例:重用 SQL 片段

<!-- 定义 SQL 片段 -->
<sql id="userColumns">id, username, email, age, created_at
</sql><!-- 在查询中引入 -->
<select id="findUserById" resultType="User">SELECT <include refid="userColumns" />FROM usersWHERE id = #{id}
</select>

这样避免了代码冗余,使 SQL 语句更加简洁易维护。

6. 动态 SQL 组合

可以通过将不同的 SQL 查询片段拼接在一起,生成动态查询。这在某些场景下非常有用,尤其是在查询条件繁多时。你可以将 SQL 片段存储为不同的 <sql> 片段,并通过 <include> 引入。

案例:动态组合查询

<!-- SQL 片段 -->
<sql id="userCondition"><where><if test="username != null and username != ''">username = #{username}</if><if test="email != null and email != ''">AND email = #{email}</if><if test="age != null">AND age = #{age}</if></where>
</sql><!-- 引用 SQL 片段 -->
<select id="findUsersByDynamicCondition" resultType="User">SELECT * FROM users<include refid="userCondition" />
</select>

7. 动态 SQL 执行优化

对于一些复杂且频繁执行的 SQL 语句,可以通过缓存机制或延迟加载机制来优化动态 SQL 的执行。

  • 一级缓存:MyBatis 默认开启一级缓存,缓存作用于会话级别,确保在一个会话中,相同的 SQL 只会执行一次。
  • 二级缓存:MyBatis 支持二级缓存,可以跨会话缓存结果集,适用于静态数据查询。

8. 嵌套查询与延迟加载

当你使用嵌套查询(如查询一个对象的同时查询其关联的子对象)时,可以通过配置延迟加载来提高性能。

<resultMap id="userResultMap" type="User"><id property="id" column="id"/><result property="username" column="username"/><result property="email" column="email"/><association property="address" column="address_id" select="findAddressById" fetchType="lazy"/>
</resultMap>

fetchType="lazy" 表示当调用 user.getAddress() 时才会执行 findAddressById 查询,避免在不需要时浪费资源。

总结

  • 高级 SQL 片段重用:使用 <sql><include> 提供了模块化 SQL 拼接的能力,降低代码冗余,提升代码维护性。
  • 动态表名和列名:通过 ${} 实现动态表名、列名替换,适合灵活多变的业务需求。
  • OGNL 表达式的灵活性:可以在 SQL 中实现更加复杂的逻辑控制。
  • 批量操作的高效实现<foreach> 在批量插入、批量更新中非常高效。
  • 缓存和延迟加载优化:结合 MyBatis 的缓存机制和延迟加载提升性能。

这些高级用法不仅增加了 MyBatis 在复杂场景下的灵活性,还能通过重用 SQL 片段、动态绑定等机制提升代码的可维护性和执行效率。

相关文章:

MyBatis动态SQL标签总结、开发手册、高阶用法(动态SQL、OGNL、批量操作、片段重用、 SQL 组合、 执行优化、嵌套查询与延迟加载)

MyBatis提供了一个非常强大的动态SQL功能&#xff0c;它使用了一组XML标签来帮助我们根据不同条件生成动态SQL。动态SQL的设计让开发者可以根据业务需求&#xff0c;灵活地构建SQL查询语句。以下是MyBatis动态SQL标签的总结。 动态SQL标签说明特点<if>条件判断语句&…...

出处不详 取数游戏

目录 取数游戏题目描述背景输入输出数据范围 题解解法优化 打赏 取数游戏 题目描述 背景 两人将 n n n个正整数围成一个圆环&#xff0c;规则如下&#xff1a; 第一名玩家随意选取数字&#xff1b;第二名玩家从与第一名玩家相邻的两个数字中选择一个&#xff1b;而后依次在…...

拉取ros2_control_demos存储库

目录 克隆存储库 方法 1: 使用 git clone 和 rosdep 安装依赖 方法 2: 使用 vcs 工具管理多个存储库 区别总结 rosdep 和 APT 的关系 网络问题 安装依赖 克隆存储库 方法 1: 使用 git clone 和 rosdep 安装依赖 下载存储库&#xff1a; mkdir -p ~/ros2_ws/src cd ~/ros…...

Apache Doris Flink Connector 24.0.0 版本正式发布

亲爱的社区伙伴们&#xff0c;Apache Doris Flink Connector 24.0.0 版本已于 2024 年 9 月 5 日正式发布。该版本新增了对 Flink 1.20 的支持&#xff0c;并支持通过 Arrow Flight SQL 高速读取 Doris 中数据。此外&#xff0c;整库同步所依赖的 FlinkCDC&#xff0c;也需升级…...

‌语音控制小夜灯的实现方案介绍

‌语音控制小夜灯的实现方案组成部分‌ 语音控制小夜灯的实现方案主要包括硬件组装和软件编程两个部分。‌ ‌硬件组装‌涉及将语音声控模块、灯泡、USB连接线等组件正确连接。首先&#xff0c;使用螺丝刀和螺丝将四个隔离柱固定在底板四个拐角处&#xff0c;同时将语音声控模…...

万龙觉醒免费辅助:VMOS云手机辅助巴克尔阵容搭配攻略!

《万龙觉醒》是一款策略类手游&#xff0c;选择合适的英雄阵容搭配能够极大提升战斗效果。而借助VMOS云手机的辅助功能&#xff0c;玩家可以更加轻松地管理游戏进程&#xff0c;优化操作体验。以下是VMOS云手机的三大核心功能&#xff0c;帮助你更好地掌控《万龙觉醒》战局。 V…...

【English】长难句翻译

这里写目录标题 技巧知识点1. 定语从句 和 状从区别2. 定从 修饰词3. who 和 whom 区别4. 除了定从、状从,还有啥?5. 怎么在长难句快速定位到主谓宾而不被各种从句中的动词影响判断6. 没有,的那种一大堆从句连起来的长难句怎么办7. 时态怎么放在翻译里总结技巧 知识点 1. 定语…...

npm login 或者 npm publish 超时timeout

场景&#xff1a;空闲时间想自己尝试下npm发布包&#xff0c;毕竟这东西可以不用&#xff0c;但不能不会 步骤很简单 1.npm login 2.npm publish 这里有个坑。。。因为想发布到npm上&#xff0c;所以这里的镜像源要换回https://registry.npmjs.org&#xff0c;不能使用淘宝镜像…...

Python的openpyxl使用記錄(包含合併單元格,圖片下載和圖片插入,設置邊框,設置背景顏色)

背景 因為公司最近要求我做一份自動化導出報告&#xff0c;內容有點多&#xff0c;為了省事&#xff0c;我選用了python&#xff0c;後面估計要自建在線辦公系統&#xff0c;這個後續再講 需要的庫 openpyxl 和Pandas 開始 Execl導入 from openpyxl import load_workbook …...

基于springboot+vue实现的在线商城系统

系统主要功能&#xff1a; &#xff08;1&#xff09;商品管理模块&#xff1a;实现了商品的基本信息录入、图片上传、状态管理等相关功能。 &#xff08;2&#xff09;商品分类模块&#xff1a;实现了分类的增删改查、分类层级管理、商品分类的关联等功能。 &#xff08;3&…...

fastjson漏洞--以运维角度进行修复

文章目录 前言一、漏洞详情二、修复过程1.通过脚本方式修复1.1.脚本修复原理1.2.脚本演示1.3.执行脚本 2. 手动升级包2.1.修复步骤2.2.遇到的问题 前言 该漏洞是三个月前由安全团队扫描出来的&#xff0c;主要影响是: FastJSON是阿里巴巴的开源JSON解析库&#xff0c;它可以解…...

82页精品PPT | 构建数字化工厂的智能制造-数字化智能制造

新模式、新技术 、新制造的挑战 中国制造业正处于转型升级的关键时期&#xff0c;面临着多方面的挑战。创新能力不足导致产品同质化严重&#xff0c;缺乏核心竞争力&#xff1b;质量管理水平参差不齐&#xff0c;影响着产品的可靠性和安全性&#xff1b;品牌价值不高&#xff…...

Python的10个日期和时间操作的实用技巧

在Python中&#xff0c;处理日期和时间是一项常见且重要的任务。datetime模块提供了丰富的功能来执行这些操作。以下是10个日期和时间操作的实用技巧及其代码演示&#xff1a; 1. 获取当前日期和时间 from datetime import datetimenow datetime.now() print(f"当前日期…...

关于大模型在产品开发中所面临的问题,利用大模型技术解决很简单!

“ 具体问题具体分析&#xff0c;大模型技术没有统一的解决方案 ” 有人说2024年是大模型应用的元年&#xff0c;而大模型在未来的发展潜力毋庸置疑&#xff0c;这也就意味着人工智能技术是下一个风口&#xff0c;因此各种各样基于大模型技术的创业公司如雨后春笋般涌现。 从…...

SpringBoot2:请求处理原理分析-利用内容协商功能实现接口的两种数据格式(JSON、XML)

文章目录 一、功能说明二、案例实现1、基于请求头实现2、基于请求参数实现 一、功能说明 我们知道&#xff0c;用ResponseBody注解标注的接口&#xff0c;默认返回给页面的是json数据。 其实&#xff0c;也可以返回xml结构的数据给页面。 这一篇就来实现一下这个小功能。 二、…...

BUUCTF 之Basic 1(BUU LFI COURSE 1)

1、启动靶场&#xff0c;会生成一个URL地址&#xff0c;打开给的URL地址&#xff0c;会看到一个如下界面 可以看到是一个PHP文件&#xff0c;非常的简单&#xff0c;就几行代码&#xff0c;判断一下是否有一个GET的参数&#xff0c;并且是file名字&#xff0c;如果是并且加载&a…...

Android 蓝牙三方和动态权限三方

记录一下最近用到的简单的框架 蓝牙 FastBle&#xff1a;Android BLE通信库的介绍与高级用法 - 简书 https://github.com/Jasonchenlijian/FastBle 动态权限: GitHub - googlesamples/easypermissions: Simplify Android M system permissions 位置权限举例,arrayOf中多个…...

点餐|基于java的电子点餐系统小程序(源码+数据库+文档)

电子点餐系统|小程序|在线点餐 目录 基于java的电子点餐系统小程序 一、前言 二、系统设计 三、系统功能设计 系统功能实现 前台&#xff1a; 后台&#xff1a; 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; …...

18、Gemini-Pentest-v1

难度 中 &#xff08;个人认为是高&#xff09; 目标 root权限 一个flag 靶机启动环境为VMware kali 192.168.152.56 靶机 192.168.152.64 信息收集 突破点大概就是web端了 web测试 访问主页直接就是目录遍历 不过进去后是一个正常的网页 简单的试了几个弱口令无果继续信息…...

MIT6.824 课程-MapReduce

MapReduce&#xff1a;在大型集群上简化数据处理 概要 MapReduce是一种编程模型&#xff0c;它是一种用于处理和生成大型数据集的实现。用户通过指定一个用来处理键值对(Key/Value)的map函数来生成一个中间键值对集合。然后&#xff0c;再指定一个reduce函数&#xff0c; 它用…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践&#xff0c;很多人以为AI已经强大到不需要程序员了&#xff0c;其实不是&#xff0c;AI更加需要程序员&#xff0c;普通人…...