MyBatis系统学习(三)——动态SQL
MyBatis 是一款优秀的持久层框架,它通过 XML 或注解方式将 SQL 语句与 Java 对象映射起来。动态 SQL 是 MyBatis 中非常强大的功能之一,能够根据不同的条件动态生成 SQL 语句。动态 SQL 通过各种标签来灵活生成 SQL,从而避免了在代码中拼接 SQL 的复杂性和冗余性。接下来,我们会详细讲解 MyBatis 中动态 SQL 的相关知识点,涵盖动态 SQL 的元素、条件查询、更新操作及复杂查询操作。
一、MyBatis 动态 SQL 标签
动态 SQL 主要通过 MyBatis 提供的一些 XML 元素来实现,这些元素会根据传递的参数、条件等动态拼装 SQL。主要的动态 SQL 元素有:
-
<if>标签- 用于判断条件,只有当条件成立时,才会生成相应的 SQL 片段。
- 语法:
<if test="条件">SQL 语句 </if> - 示例:
上述 SQL 语句中,只有当<select id="findUser" parameterType="int" resultType="User">SELECT * FROM userWHERE 1=1<if test="id != null">AND id = #{id}</if> </select>id不为 null 时,才会拼接AND id = #{id}这部分 SQL。
-
<choose>,<when>,<otherwise>标签- 类似于 Java 中的 switch-case 语法,用于多条件选择。
<choose>标签包含若干<when>,如果多个<when>条件都不满足,可以用<otherwise>作为默认的条件。 - 语法:
<choose><when test="条件1">SQL 语句1</when><when test="条件2">SQL 语句2</when><otherwise>默认 SQL 语句</otherwise> </choose> - 示例:
<select id="findUser" parameterType="map" resultType="User">SELECT * FROM user<where><choose><when test="name != null">name = #{name}</when><when test="age != null">age = #{age}</when><otherwise>status = 'active'</otherwise></choose></where> </select>
- 类似于 Java 中的 switch-case 语法,用于多条件选择。
-
<where>标签- 用来自动处理 WHERE 子句前缀问题。
<where>会智能地在第一个条件前添加WHERE,并自动去掉多余的AND或OR。 - 示例:
这里,如果<select id="findUser" parameterType="map" resultType="User">SELECT * FROM user<where><if test="name != null">AND name = #{name}</if><if test="age != null">AND age = #{age}</if></where> </select>name和age都为空,<where>标签会避免生成无效的WHERE子句。
- 用来自动处理 WHERE 子句前缀问题。
-
<set>标签- 在更新操作中常用,类似于
<where>,<set>也会自动处理SET关键字前后的逗号问题。 - 示例:
在生成 SQL 时,<update id="updateUser" parameterType="User">UPDATE user<set><if test="name != null">name = #{name},</if><if test="age != null">age = #{age},</if></set>WHERE id = #{id} </update><set>标签会自动处理最后一项的逗号。
- 在更新操作中常用,类似于
-
<trim>标签trim标签用于自定义去掉前后多余的字符,替代where和set标签。它有四个重要的属性:prefix: SQL 片段的前缀,如WHERE或SET。prefixOverrides: 需要去掉的前缀,如AND、OR。suffix: SQL 片段的后缀。suffixOverrides: 需要去掉的后缀,如,。
- 示例:
<select id="findUser" parameterType="map" resultType="User">SELECT * FROM user<trim prefix="WHERE" prefixOverrides="AND"><if test="name != null">AND name = #{name}</if><if test="age != null">AND age = #{age}</if></trim> </select>
-
<foreach>标签- 用于处理集合类型的参数,比如
List或数组,通常用于IN查询或批量插入操作。 - 重要属性:
collection: 要遍历的集合,通常是List或Array。item: 当前集合元素的别名。separator: 元素之间的分隔符,如,。open和close: 分别表示 SQL 片段的开头和结尾字符。
- 示例:
<select id="findUserByIds" parameterType="list" resultType="User">SELECT * FROM userWHERE id IN<foreach collection="list" item="id" open="(" separator="," close=")">#{id}</foreach> </select>
- 用于处理集合类型的参数,比如
二、条件查询的使用
在实际开发中,条件查询是非常常见的需求。MyBatis 中利用动态 SQL 能够灵活生成条件查询语句,通常使用 <if> 标签来控制条件的生成。
示例:简单条件查询
<select id="findUserByCondition" parameterType="User" resultType="User">SELECT * FROM user<where><if test="name != null">AND name = #{name}</if><if test="age != null">AND age = #{age}</if></where>
</select>
在上面的例子中,只有当 name 或 age 不为空时,才会生成对应的条件。这样可以避免生成无效的 SQL,提升查询效率。
示例:多条件选择查询
<select id="findUserByCondition" parameterType="User" resultType="User">SELECT * FROM user<where><choose><when test="name != null">name = #{name}</when><when test="age != null">age = #{age}</when><otherwise>status = 'active'</otherwise></choose></where>
</select>
这个例子中,choose 标签确保只有一个条件成立时才会生成对应的 SQL。如果多个条件不成立,则使用 otherwise 语句。
三、动态更新操作
动态 SQL 在更新操作中也非常有用。通常,我们在更新时会根据实际情况只更新某些字段,而不是全部字段。MyBatis 提供了 <set> 标签来方便地生成动态更新语句。
示例:动态更新用户信息
<update id="updateUser" parameterType="User">UPDATE user<set><if test="name != null">name = #{name},</if><if test="age != null">age = #{age},</if><if test="email != null">email = #{email},</if></set>WHERE id = #{id}
</update>
在这个例子中,只有不为空的字段才会被更新,<set> 标签确保了 SQL 语句中不会出现多余的逗号。
四、复杂查询操作
在复杂查询中,动态 SQL 的优势更为明显。我们可以根据多种条件动态生成查询语句,并使用 join、子查询等进行复杂操作。
示例:动态查询用户及其订单
<select id="findUserWithOrders" resultMap="userOrderMap">SELECT u.*, o.*FROM user uLEFT JOIN orders o ON u.id = o.user_id<where><if test="u.name != null">u.name = #{u.name}</if><if test="o.status != null">AND o.status = #{o.status}</if></where>
</select>
这个查询会根据用户信息和订单状态动态生成 SQL,可以方便地查询用户及其订单。
五、总结
MyBatis 的动态 SQL 为开发者提供了灵活、可扩展的 SQL 生成方式。通过使用 <if>、<choose>、<where>、<set>、<foreach> 等标签,能够根据条件动态生成 SQL,简化了代码,避免了 SQL 拼接的复杂性和冗余性。
动态 SQL 的优势在于:
- 简化 SQL 编写:开发者可以通过 XML 或注解方式编写复杂的 SQL 逻辑。
- 提升代码可读性:通过清晰的条件控制和 SQL 生成逻辑,代码更加清晰。
- 减少代码冗余:避免了在 Java 代码中拼接 SQL 字符串的繁琐操作。
掌握动态 SQL 的使用对于 MyBatis 框架的实际应用非常重要,在复杂的业务逻辑中尤为常见。
相关文章:
MyBatis系统学习(三)——动态SQL
MyBatis 是一款优秀的持久层框架,它通过 XML 或注解方式将 SQL 语句与 Java 对象映射起来。动态 SQL 是 MyBatis 中非常强大的功能之一,能够根据不同的条件动态生成 SQL 语句。动态 SQL 通过各种标签来灵活生成 SQL,从而避免了在代码中拼接 S…...
get_property --Cmakelist之中
get_property 是 CMake 中用于获取目标、目录、变量或文件等属性的命令。它可以提取某个特定属性的值,以便在构建脚本的其他地方使用。 语法 get_property(<variable> <TYPE> <name> PROPERTY <property-name> [SET | DEFINED | BRIEF_DO…...
【Redis】Redis 典型应用 - 分布式锁原理与实现
目录 Redis 典型应⽤ - 分布式锁什么是分布式锁分布式锁的基础实现引⼊过期时间引⼊校验 id引⼊ lua引⼊ watch dog (看⻔狗)引⼊ Redlock 算法其他功能 Redis 典型应⽤ - 分布式锁 什么是分布式锁 在⼀个分布式的系统中, 也会涉及到多个节点访问同⼀个公共资源的…...
Pybind11的使用
目录 1. 引言1.1 Pybind11 简介1.2 为什么需要 Pybind11 2. 使用 Pybind11 进行 C 与 Python 交互2.1 基本用法2.2 编译与生成共享库2.2.1 在 Linux 下编译2.2.2 在 macOS 下编译2.2.3 编译选项详解 2.3 在 Python 中使用编译后的模块 3. 高级用法与注意事项3.1 绑定类和复杂数…...
鸿蒙-沉浸式pc端失效
咨询描述: 因PC北向窗口涉及沉浸式时,预计发生接口废弃导致不兼容变更,涉及接口setImmersiveModeEnabledState、setWindowLayoutFullSceen 如果应用支持沉浸式(窗口全屏且隐藏状态栏&标题栏&Dock栏)࿰…...
【资料分析】刷题日记1
第一套 第二个是相比2019年的增长率,错找为同比增长率 延申: 当出口和进口相比2019年的增长率相同时,可以用盐水解决 √ 一个假设分配(第二次是1.4取1)加法对比选项 基期倍数: 求A是B的多少倍&#x…...
nodejs+express+vue教辅课程辅助教学系统 43x2u前后端分离项目
目录 技术栈具体实现截图系统设计思路技术可行性nodejs类核心代码部分展示可行性论证研究方法解决的思路Express框架介绍源码获取/联系我 技术栈 该系统将采用B/S结构模式,开发软件有很多种可以用,本次开发用到的软件是vscode,用到的数据库是…...
96-javahashmap底层原理
HashMap是Java集合框架中的一个重要类,底层是基于哈希表实现的。哈希表是一种数据结构,可以通过哈希函数来提高查找、插入和删除操作的效率。 以下是HashMap底层实现的一些关键点: 哈希算法:HashMap使用哈希算法来计算键的哈希值…...
AI逻辑推理入门
参考数据鲸 (linklearner.com) 1. 跑通baseline 报名 申领大模型API 模型服务灵积-API-KEY管理 (aliyun.com) 跑通代码 在anaconda新建名为“LLM”的环境,并安装好相应包后,在jupyter notebook上运行baseline01.ipynb 2. 赛题解读 一般情况下,拿到一个赛题之后,我们需…...
力扣3014.输入单词需要的最少按键次数I
给你一个字符串 word,由 不同 小写英文字母组成。 电话键盘上的按键与 不同 小写英文字母集合相映射,可以通过按压按键来组成单词。例如,按键 2 对应 ["a","b","c"],我们需要按一次键来输入 "…...
【Git】远程仓库
本博客的环境是 Ubuntu/Linux 文章目录 集中式与分布式的区别远程仓库新建远程仓库克隆远程仓库向远程仓库推送从远程仓库拉取 配置Git忽略指定文件给命令配置别名 标签管理创建标签操作标签 多人协作本地分支与远程分支连接场景一场景二 集中式与分布式的区别 引荐自关于Git这…...
苹果手机铃声怎么设置自己的歌?3个方法自定义手机铃声
苹果手机内部的手机铃声库只有固定的几首铃声,且都是纯音乐,比较单调,并不是所有用户都喜欢这些铃声。那么,苹果手机铃声怎么设置自己的歌呢?小编这里有3个方法,可以教大家如何将手机铃声设置成自己喜欢的歌…...
828华为云征文|华为Flexus云服务器搭建Cloudreve私人网盘
一、华为云 Flexus X 实例:开启高效云服务新篇🌟 在云计算的广阔领域中,资源的灵活配置与卓越性能犹如璀璨星辰般闪耀。华为云 Flexus X 实例恰似一颗最为耀眼的新星,将云服务器技术推向了崭新的高度。 华为云 Flexus X 实例基于…...
【AI学习】AI绘画发展简史
无意中读了一篇发表自2022年的文章,《AI绘画何以突飞猛进? 从历史到技术突破, 一文读懂火爆的AI绘画发展史》,写的比较有意思,科普了好多我原来不知道的历史。 简单提炼一下,做个笔记。 AI绘画重要事件 2012年 Google两位大名…...
使用LangChain创建简单的语言模型应用程序【快速入门指南】
## 引言在这篇文章中,我们将展示如何使用LangChain构建一个简单的语言模型(LLM)应用程序。这个应用程序的功能是将文本从英语翻译成其他语言。尽管应用程序的逻辑相对简单,但它能够帮助我们学习如何使用LangChain进行更多复杂的功…...
嵌入式人工智能项目及人工智能应用项目——大合集列表查阅
本文的项目合集列表可能更新不及时(会及时更新),可查阅实时更新的链接如下。 嵌入式人工智能及人工智能应用项目合集实时更新链接如下: 阿齐嵌入式人工智能及人工智能应用项目合集 (kdocs.cn)https://www.kdocs.cn/l/cc97tuieys4…...
心觉:成功学就像一把刀,有什么作用关键在于使用者(一)
Hi,我是心觉,与你一起玩转潜意识、脑波音乐和吸引力法则,轻松掌控自己的人生! 挑战每日一省写作173/1000天 很多人觉得成功学是鸡汤,是没用的,甚至是骗人的 我先保持中立,不知道对不对 我们先…...
GAMES101(10节,几何)
Geometry implicit隐式几何表示: 函数f(x,y,z): 根据函数fn描述几何,遍历所有空间内 的点,如果带入xyz到函数f(x,y,z)结果0那就绘制这个点 如果xyz求值结果>0表示在几何外,0在表面,<0在几何内 构造几何csg(…...
Android 中音频焦点的使用场景及示例
Android 中音频焦点的使用场景及代码示例 一、音频焦点简介 在 Android 系统中,音频焦点(Audio Focus)是一种机制,用于管理多个应用程序同时播放音频时的冲突。当一个应用程序请求音频焦点并获得它时,其他应用程序在…...
2. JDBC驱动是什么?如何在Java项目中配置MySQL的JDBC驱动?
JDBC驱动 是一种软件组件,它使Java应用程序能够与数据库进行交互。JDBC驱动是JDBC API的实现,负责将Java程序中的标准JDBC方法调用转化为数据库特定的操作。每个数据库(如MySQL、PostgreSQL、Oracle等)都有对应的JDBC驱动程序&…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
