详细分析Mybatis中的<foreach>标签
目录
- 前言
- 1. 基本语法
- 2. Demo
- 3. 实际例子
前言
对于Java专栏:Java专栏
对于Mybatis的相关知识可看我之前的文章:Mybatis从入门到精通(全)
对于其余Java框架可看我之前的文章:java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
对于上述Mybatis中曾有讲过foreach标签!此篇博客对其标签进行拓展
1. 基本语法
MyBatis中的<foreach>
标签是用于迭代集合或数组的元素,生成对应的SQL片段,以便在动态SQL中使用。
该标签通常用于循环处理参数集合,生成多个相同的SQL片段,以实现批量操作或动态条件查询。
其基本的语法如下:
<foreach collection="collectionName" item="itemName" index="indexName" open="(" close=")" separator=",">#{itemName}
</foreach>
对应的属性如下:(只有collection和item是必选,其他都是可选参数)
collection
: 指定要迭代的集合或数组的属性名,表示传入的参数的数据类型。
该属性是必须指定的,用于指定要进行foreach操作的对象。item
: 指定在迭代过程中每个元素的别名,表示本次迭代获取的元素。
若collection为List、Set或者数组,则表示其中的元素;
若collection为map,则代表key-value的value。
该参数是必选的。index
: 指定在迭代过程中每个元素的索引,仅对集合有效。
在遍历List时,index表示元素的索引;在遍历Map时,index表示Map的key。该参数是可选的。open
: 指定迭代开始时的字符串,最常用的是左括弧'('
。
MyBatis会将该字符拼接到整体的SQL语句之前,并且只拼接一次。该参数是可选的。close
: 指定迭代结束时的字符串,最常用的是右括弧')'
。
MyBatis会将该字符拼接到整体的SQL语句之后。该参数是可选的。separator
: 指定每次迭代之间的分隔符。
在SQL语句中,用于分隔不同元素的值。例如,1,2,3之间的,。该参数是可选的。
2. Demo
下面是一个简单的例子,假设有一个包含多个用户ID的集合,我们想要生成一个SQL语句查询这些用户:
<select id="selectUsersByIds" resultType="User">SELECT * FROM usersWHERE id IN<foreach collection="userIds" item="userId" open="(" close=")" separator=",">#{userId}</foreach>
</select>
在这个例子中,userIds是一个包含用户ID的集合,<foreach>
标签会生成类似于IN (id1, id2, id3)的SQL片段。
另外,如果使用MyBatis的动态SQL功能,可以在<if>
标签内使用<foreach>
,以根据条件动态生成SQL片段,以下是一个例子,假设有一个条件查询的场景,根据用户选择的角色列表进行查询:
<select id="selectUsersByRoles" resultType="User">SELECT * FROM users<where><if test="roles != null and roles.size > 0">AND id IN<foreach collection="roles" item="role" open="(" close=")" separator=",">#{role}</foreach></if></where>
</select>
在这个例子中,selectUsersByRoles是一个动态SQL查询,它根据用户传入的roles参数动态生成SQL条件。
- 如果roles不为空且包含元素,那么
<if>
标签内的内容会生效,生成类似于AND id IN (role1, role2, role3)
的SQL片段。 - 如果roles为空或不包含元素,该条件会被忽略,从而生成不包含AND的SQL语句。
在实际应用中,这种动态SQL的使用可以根据不同的业务需求动态构建查询条件,使SQL语句更加灵活和可复用。
3. 实际例子
结合实战中的例子,讲解更加透彻
批量插入
,即列表中有多个元素,代码示例:
<insert id="saveForList" parameterType="java.util.List">INSERT INTO E_DEVICE_TEMP_ALARM_HIST(DEVICE_NAME, BATTERY_TEMP, SEND_TO_DRIVER, CREATE_TIME, UPDATE_TIME, SENDER, SUGGESTION)<foreach collection="temperatureAlarmHistList" item="temperatureAlarmHist" separator="union all" open="(" close=")">SELECT#{temperatureAlarmHist.deviceName, jdbcType=VARCHAR},#{temperatureAlarmHist.batteryTemp, jdbcType=VARCHAR},#{temperatureAlarmHist.sendToDriver, jdbcType=INTEGER},#{temperatureAlarmHist.createTime, jdbcType=DATE},#{temperatureAlarmHist.updateTime, jdbcType=DATE},#{temperatureAlarmHist.sender, jdbcType=VARCHAR},#{temperatureAlarmHist.suggestion, jdbcType=VARCHAR}FROM DUAL</foreach>
</insert>
动态SQL语句
,更新语句也同理:
<update id="removeRuleDetailByRuleId" >update equipment_change_shifts_rule_detail set is_deleted = 1 where rule_id IN<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">#{id}</foreach>
</update>
结合if语句
,且参数位置可以随意:
<select id="trees" resultMap="treeNodeResultMap">select id, parent_id, equipment_name as title, id as 'value', id as 'key',location from equipment_architecture where is_deleted = 0<if test="tenantId!=null">and tenant_id = #{tenantId}</if>and id in<foreach close=")" collection="ids" item="listItem" open="(" separator=",">#{listItem}</foreach>
</select>
相关文章:
详细分析Mybatis中的<foreach>标签
目录 前言1. 基本语法2. Demo3. 实际例子 前言 对于Java专栏:Java专栏 对于Mybatis的相关知识可看我之前的文章:Mybatis从入门到精通(全) 对于其余Java框架可看我之前的文章:java框架 零基础从入门到精通的学习路线 附…...
linux-挂载Samba共享
linux-挂载Samba共享 1、linux服务器启动Samba共享服务 2、客户端电脑安装cifs-utils dnf install cifs-utils # 或 yum install cifs-utils3、挂载共享目录 # 创建挂目录 mkdir /share # 使用mount命令挂在共享目录,-t协议类型 -o用户名密码 共享目录访问地址 挂…...

Java入门IDEA基础语法
1:Java入门 1.1 Java简介 Java是什么: Java是一门非常优秀的计算机语言 语言:人与人交流沟通的表达方式 计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言 Java之父:詹姆斯高斯林(James Gosli…...

【小白专用】C# 连接 MySQL 数据库
C# – Mysql 数据库连接 1. 配置环境 #前提:电脑已安装Mysql服务; Visual Studio 安装Mysql依赖库: 工具 -> NuGet 包管理器 -> 管理解决方案的 NuGet程序包 —> 搜索, 安装Mysql.Data (Oracle); (安装成功后&…...
Django登录注销视图
Django在身份验证框架中包含了一些你可以直接使用的表单和视图。在大多数情况下,可以使用默认的Django认证视图。 Django在django.contrib.auth.views提供了以下基于类的视图来处理身份验证: LoginView:处理登录表单并登录用户 LogoutView&a…...
云原生到底是什么意思
云原生到底是什么意思? 引言 随着云计算技术的迅速发展,云原生成为了一个备受关注的话题。云原生不仅仅是一种新的软件架构,更是一种变革性的开发方法论。本文将深入解析云原生的意义、特点以及为什么它在现代软件开发中变得如此重要。 云…...

【银行测试】银行项目,信用卡业务测试+常问面试(三)
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 银行测试-信用卡业…...

AI大模型学习笔记之二:什么是 AI 大模型的训练和推理?
在人工智能(AI)的领域中,我们经常听到训练(Training) 和 推理(Inference) 这两个词汇,它们是构建强大 AI 模型的关键步骤。我们通过类比人类的学习过程来理解这两个概念,可以更加自然而生动地理…...

【MATLAB源码-第113期】基于matlab的孔雀优化算法(POA)机器人栅格路径规划,输出做短路径图和适应度曲线。
操作环境: MATLAB 2022a 1、算法描述 POA(孔雀优化算法)是一种基于孔雀羽毛开屏行为启发的优化算法。这种算法模仿孔雀通过展开其色彩斑斓的尾羽来吸引雌性的自然行为。在算法中,每个孔雀代表一个潜在的解决方案,而…...

iphone 5s的充电时序原理图纸,iPAD充电讲解
上一篇写了iphone 5的时序。那是电池供电的开机时序。iphone 5s也是差不多的过程,不说了。现在看iphone5s手机充电时候的时序。iphone5s充电比iphone5充电简单了很多。 首先是usb接口接到手机上,usb线连接到J7接口上。J7接口不只是接usb,还能…...

react基础入门
1,了解react react并不是一个MVC框架,他只是一个很强大的javaScript库,主要作用是用来构建UI界面。 react的核心是封装一个个大大小小的组件(小到一个按钮,大到一个页面)来构建复杂的UI界面,每…...

spring boot学习第八篇:通过spring boot、jedis实现秒单
参考:Redis实现分布式锁的7种方案 - 知乎 1、 准备数据库表,如下SQL表示库存表,有主键ID和库存数量字段 CREATE TABLE t_stock (id bigint(20) NOT NULL AUTO_INCREMENT,quantity bigint(20) NOT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEF…...
NineAi 新版AI系统网站源码 ChatGPT
简介: Nine AI.ChatGPT是基于ChatGPT开发的一个人工智能技术驱动的自然语言处理工具,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,真正像人类一样来聊天交流,甚至能完成撰写邮件、视频脚本、文案、翻译、代码,写论文等任务。 NineAi 新版A…...
开源监控服务一瞥:Prometheus、Grafana、Zabbix、Nagios、Icinga和Open-Falcon
前言 随着信息技术的发展,监控服务在维护系统稳定性和性能方面变得越来越重要。本文将比较一些流行的开源监控服务,以帮助你选择适合你需求的解决方案。 监控服务对比 监控服务特点优势不足性能扩展性安全性Prometheus- 多维度数据模型- 监控容器化环…...

使用WAF防御网络上的隐蔽威胁之扫描器
在网络安全领域,扫描器是用于侦察和识别网络系统漏洞的工具。 它们可以帮助网络管理员识别安全漏洞,也可能被攻击者用来寻找攻击目标。 扫描器的基本概念 定义:扫描器是一种自动化工具,用于探测网络和服务器中的漏洞、开放端口、…...
企业信息安全管理制度
随着信息化程度的日益推进,企业信息的脆弱性也日益暴露。如何规范日趋复杂的信息安全保障体系建设,如何进行信息风险评估保护企业的信息资产不受侵害,已成为当前行业实现信息化运作亟待解决的问题。 一、企业的信息及其安全隐患 在我公司&am…...
Qt中的线程池
Qt中的线程池 目录 1 为什么需要线程池 2 Qt中有哪些方式实现线程池 3 如何通过QThreadPool类实现线程池 4 如何通过QtConcurrent库实现线程池 5 如何通过自定义的方式实现线程池 5 小结 1 为什么需要线程池 线程池是多线程编程中常用的一种技术,可以帮助管理系统中…...
使用Spring Boot集成中间件:Elasticsearch基础->提高篇
使用Spring Boot集成中间件:Elasticsearch基础->提高篇 导言 Elasticsearch是一个开源的分布式搜索和分析引擎,广泛用于构建实时的搜索和分析应用。在本篇博客中,我们将深入讲解如何使用Spring Boot集成Elasticsearch,实现数…...

【Docker】Dockerfile构建最小镜像
🥳🥳Welcome 的Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于Docker的相关操作吧 目录 🥳🥳Welcome 的Huihuis Code World ! !🥳🥳 前言 一.Dockerfile是什么 二.Dock…...
【严重】GitLab 以其他用户身份执行 Slack 命令
漏洞描述 GitLab 是由GitLab公司开发的、基于Git的集成软件开发平台。使用 Slack 命令在 Slack 聊天环境中运行常见的 GitLab 操作。 GitLab 受影响版本中,由于配置Slack/Mattermost 集成时,未正确验证用户身份信息,导致攻击者可以使用其他…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...

实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...

【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
Windows 下端口占用排查与释放全攻略
Windows 下端口占用排查与释放全攻略 在开发和运维过程中,经常会遇到端口被占用的问题(如 8080、3306 等常用端口)。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口,帮助你高效解决此类问题。 一、准…...