Spring Boot + MyBatis/MyBatis Plus:XML中循环处理List参数的终极指南

重要提醒:使用@Param注解时,务必导入正确的包!
import org.apache.ibatis.annotations.Param;
很多开发者容易错误导入Spring的@Param,导致参数绑定失败!

一、为什么需要传递List参数?

最常见的场景是动态构建IN查询

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

当我们需要根据前端传入的多个值查询时,就需要将List集合作为参数传递给Mapper。


二、基础版:MyBatis原生List传参

1. Mapper接口定义(注意@Param导入)
// !!!必须导入MyBatis的@Param包!!!
import org.apache.ibatis.annotations.Param;public interface UserMapper {// 使用@Param注解指定参数名List<User> selectByIds(@Param("idList") List<Long> idList);
}
2. XML映射文件实现
<select id="selectByIds" resultType="User">SELECT * FROM usersWHERE id IN<foreach collection="idList" item="id" open="(" separator="," close=")">#{id}</foreach>
</select>
核心标签解析:
属性说明示例值
collection传入的集合参数名idList
item循环中当前元素的别名id
open循环开始前的字符串(
separator元素间的分隔符,
close循环结束后的字符串)
3. 实际生成的SQL

当传入List<Long> ids = Arrays.asList(1L, 2L, 3L)时:

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

三、避坑重点:@Param的正确使用

常见错误1:导入错误包
// ❌ 错误:导入了Spring的Param包
import org.springframework.data.repository.query.Param;// ✅ 正确:必须使用MyBatis的Param包
import org.apache.ibatis.annotations.Param;
常见错误2:忘记添加@Param注解
// ❌ 错误:缺少@Param注解会导致XML中无法识别参数
List<User> selectByIds(List<Long> idList);// ✅ 正确:必须添加@Param注解
List<User> selectByIds(@Param("idList") List<Long> idList);

四、MyBatis Plus的优雅实现

1. 使用QueryWrapper(无需XML)
public List<User> getUsersByIds(List<Long> ids) {return userMapper.selectList(new QueryWrapper<User>().in("id", ids));
}
2. Lambda表达式写法(推荐)
public List<User> getUsersByIds(List<Long> ids) {return userMapper.selectList(Wrappers.<User>lambdaQuery().in(User::getId, ids));
}

注意:MyBatis Plus的Wrapper方式不需要@Param注解


五、扩展应用场景

场景1:List处理
// Mapper
List<User> selectByNames(@Param("nameList") List<String> nameList);// XML
<foreach collection="nameList" item="name" open="(" separator="," close=")">#{name}
</foreach>
场景2:List<实体对象>
// Mapper
List<User> selectByConditions(@Param("userList") List<User> userList);// XML
<foreach collection="userList" item="user" separator=" OR ">(name = #{user.name} AND age > #{user.age})
</foreach>
场景3:多List参数
// Mapper
List<User> searchUsers(@Param("ids") List<Long> ids, @Param("names") List<String> names);// XML
<where><if test="ids != null and !ids.isEmpty()">id IN<foreach collection="ids" item="id" open="(" separator="," close=")">#{id}</foreach></if><if test="names != null and !names.isEmpty()">AND name IN<foreach collection="names" item="name" open="(" separator="," close=")">#{name}</foreach></if>
</where>

六、特殊类型处理技巧

1. 枚举类型处理
// Mapper
List<User> selectByStatus(@Param("statusList") List<UserStatus> statusList);// XML
<foreach collection="statusList" item="status" open="(" separator="," close=")">#{status, typeHandler=org.apache.ibatis.type.EnumTypeHandler}
</foreach>
2. 日期范围查询
// Mapper
List<User> selectByDates(@Param("dateList") List<Date> dates);// XML
<foreach collection="dateList" item="date" separator=" OR ">create_time BETWEEN #{date} AND DATE_ADD(#{date}, INTERVAL 1 DAY)
</foreach>

七、性能优化与避坑指南

1. 空集合安全处理
<select id="safeSelect">SELECT * FROM users<where><if test="idList != null and !idList.isEmpty()">id IN<foreach collection="idList" ... /></if></where>
</select>
2. 大数据量分批查询
// 每500条执行一次查询
public List<User> batchSelect(List<Long> allIds) {List<User> result = new ArrayList<>();int batchSize = 500;for (int i = 0; i < allIds.size(); i += batchSize) {List<Long> batchIds = allIds.subList(i, Math.min(i + batchSize, allIds.size()));result.addAll(userMapper.selectByIds(batchIds));}return result;
}
3. SQL注入防护
<!-- 安全写法:使用#{}预编译 -->
<foreach collection="names" item="name">#{name}  <!-- 安全 -->
</foreach><!-- 危险写法:${}直接拼接 -->
<foreach collection="names" item="name">'${name}' <!-- 存在SQL注入风险! -->
</foreach>

八、完整可运行示例

Controller
@RestController
@RequestMapping("/users")
public class UserController {@PostMapping("/by-ids")public List<User> getUsersByIds(@RequestBody List<Long> ids) {return userService.getUsersByIds(ids);}
}
Service
@Service
@RequiredArgsConstructor
public class UserService {private final UserMapper userMapper;public List<User> getUsersByIds(List<Long> ids) {if (ids == null || ids.isEmpty()) {return Collections.emptyList();}// 超过1000条自动分批return ids.size() > 1000 ? batchSelect(ids) : userMapper.selectByIds(ids);}
}
Mapper XML
<mapper namespace="com.example.mapper.UserMapper"><select id="selectByIds" resultType="User">SELECT id, name, email FROM users<where><if test="idList != null and !idList.isEmpty()">id IN<foreach collection="idList" item="id" open="(" separator="," close=")">#{id}</foreach></if></where></select>
</mapper>

总结:核心要点回顾

  1. 必须使用正确的@Param包
    import org.apache.ibatis.annotations.Param;

  2. XML循环核心语法

    <foreach collection="参数名" item="元素名" open="开始符" separator="分隔符" close="结束符">#{元素名}
    </foreach>
    
  3. 最佳实践选择

    • 简单查询:MyBatis Plus Wrapper
    • 复杂SQL:MyBatis XML + foreach
    • 超大数据:分批查询
  4. 安全防护

    • 始终使用#{}防止SQL注入
    • 空集合检查避免全表扫描
  5. 特殊类型处理

    • 枚举:添加typeHandler
    • 日期:指定jdbcType=TIMESTAMP

最后提醒: 当遇到参数绑定问题时,首先检查@Param导入的包是否正确,这是最常见的错误根源!

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

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

相关文章

Design Compiler:自适应重定时(Adaptive Retiming)

相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 简介 重定时是DC Ultra引入的一种时序优化技术&#xff0c;可以将时序单元&#xff08;触发器和锁存器&#xff09;穿越组合逻辑前后移动&#xff0c;以优化设…

解决kali Linux在VMware中的全局缩放问题

在每次启动kali时&#xff0c;因为屏幕分辨率过高&#xff0c;系统整体特别小&#xff0c;该怎么操作调整合适呢 在搜索中搜索kali HiDPI Mode 选择yes 然后就会自动调整合适了

Python关键字梳理

在 Python 中&#xff0c;关键字&#xff08;Keywords&#xff09;是具有特殊含义的保留字&#xff0c;它们用于定义语法和结构。async 是 Python 3.5 引入的关键字&#xff0c;用于支持异步编程&#xff08;Asynchronous Programming&#xff09;。下面我将详细讲解 async 及其…

结构体实战:用Rust编写矩形面积计算器

文章目录结构体实战&#xff1a;用Rust编写矩形面积计算器&#x1f4d0; 问题描述1️⃣ 基础版&#xff1a;独立变量&#xff08;混乱版&#xff09;2️⃣ 进阶版&#xff1a;使用元组3️⃣ 终极版&#xff1a;使用结构体&#xff08;优雅版&#xff09;&#x1f3af; 运行结果…

基于开源链动2+1模式AI智能名片S2B2C商城小程序的场景零售创新研究

摘要&#xff1a;本文聚焦场景消费逻辑&#xff0c;探讨开源链动21模式AI智能名片S2B2C商城小程序在场景零售中的应用。通过分析场景消费中消费者体验的关键作用&#xff0c;结合该技术组合的特性&#xff0c;阐述其如何优化场景内容、增强场景美感&#xff0c;为消费者创造超乎…

新发布:26考研院校和专业大纲

复习方向错了&#xff0c;努力可能白费 近日&#xff0c;多所高校陆续发布2026年硕士研究生招生考试自命题科目大纲&#xff0c;为备考的学子们指明了复习方向。今年的考纲有哪些重要变化&#xff1f;又该如何应对&#xff1f;本文为你全面梳理&#xff01; 院校和专业发布详情…

matlab/Simulink-全套50个汽车性能建模与仿真源码模型9

50个simulink模型&#xff08;所有模型罗列如下&#xff0c;没罗列就是没有&#xff0c;包含子模块总共50个。&#xff09; 基于汽车驱动力-行驶阻力平衡图的汽车动力性仿真模型 基于汽车动力特性图的汽车动力性仿真模型 基于汽车功率平衡图的汽车动力性仿真模型 电动汽车动力…

为什么星敏感器(Star Tracker)需要时间同步?—— 从原理到应用的全解析

为什么星敏感器&#xff08;Star Tracker&#xff09;需要时间同步&#xff1f;—— 从原理到应用的全解析 引言 在卫星姿态控制系统中&#xff0c;星敏感器&#xff08;Star Tracker, 简称“星敏”&#xff09; 是最精确的姿态测量设备之一&#xff0c;其精度可达角秒级&…

【Cocos TypeScript 零基础 24.1】

目录 首次实战开发心得实战项目<修仙录游戏> 首次实战开发心得 遇到的技术问题也多 发表问题也不少 收入问题 本人都将会写篇专栏总结一下 实战项目<修仙录游戏> 上图是已上线的实战项目二维码 耗费的时间太久了 下次将跟新开发遇到的各种奇奇怪怪的问题 各位看…

Linux关机指令详解:shutdown命令的使用指南

掌握shutdown命令的正确使用对于Linux系统管理员至关重要&#xff0c;它不仅能确保系统安全关闭&#xff0c;还能避免数据丢失和用户工作中断。 目录 一、基本语法 二、常用选项 三、使用示例 立即关机 10分钟后关机 指定时间关机&#xff08;如23:00&#xff09; 重启系…

青少年编程与数学 02-022 专业应用软件简介 08 电子设计自动化软件

青少年编程与数学 02-022 专业应用软件简介 08 电子设计自动化软件一、什么是EDA软件&#xff08;一&#xff09;定义与起源&#xff08;二&#xff09;功能与分类&#xff08;三&#xff09;技术发展趋势二、EDA软件在当前国际竞争中的重要性&#xff08;一&#xff09;技术壁…

TypeScript系列:第六篇 - 编写高质量的TS类型

掌握这些&#xff0c;ts类型声明事半功倍 &#x1f4aa;&#x1f3fb; 不要做 永远不要使用类型 Number、String、Boolean、Symbol 或 Object 这些类型指的是非原始装箱对象&#xff0c;使用 number、string、boolean 和 symbol 类型不要使用 any 作为类型&#xff0c;除非正在…

逐步构建高性能http服务器及聊天室服务器

目录 如何拿到浏览器发来的http请求 如何给浏览器发送响应 响应基本原理 给浏览器发送一个网页作为响应 给浏览器发送一个图片作为响应 接下来我们要做什么 完善业务逻辑 浏览器如何访问特定文件 访问根目录下的文件 访问子文件夹下的文件 习惯性目录结构 GET请求带…

水下航行器外形分类详解

在水下航行器的设计领域&#xff0c;外形是影响其性能和功能的关键因素之一。根据不同的设计目的和应用场景&#xff0c;水下航行器的外形可以按照多种方式进行分类。 本文将详细介绍几种常见的分类方式及其对应的外形特点。 按流体动力布局分类 标准回转体 外形标准回转体外…

Ubuntu:Mysql服务器

mariadb与mysql完全兼容&#xff0c;使用时感受不到差别 目录 1 mariadb的安装2 启动mysql3 关闭防火墙4 连接到mysql5 Mysql的配置文件6 Mysql远程访问 1 mariadb的安装 apt install mariadb-server检查安装 ls /etc/init.d2 启动mysql service mysql restart3 关闭防火墙…

使用systemd 监控服务并实现故障自动重启

一、为什么需要自动重启&#xff1f; 在生产环境中&#xff0c;服务可能因内存溢出、资源竞争、外部依赖中断等问题意外崩溃。手动恢复效率低下&#xff0c;而 systemd 的自动重启机制可在秒级内恢复服务&#xff0c;显著提升系统可用性。 ⚙️ 二、systemd 自动重启的核心配置…

在 React 中使用 WebSockets 构建实时聊天应用程序

实时通信已成为现代 Web 应用程序&#xff08;尤其是在聊天应用程序中&#xff09;不可或缺的功能。实时通信提供了一种强大的方法来实现客户端和服务器之间的实时双向通信。在本指南中&#xff0c;我们将逐步讲解如何使用React WebSockets构建实时聊天应用程序。 先决条件 在…

实验五-Flask的简易登录系统

一、实验目的和任务 1.掌握Flask框架的基本使用方法 2.理解Web应用的会话管理机制 3.实现用户认证系统的基本功能 4.学习模板继承和表单处理技术 要求&#xff1a;请将思考题的答案写在实验报告中 二、实验内容 1.基础环境搭建&#xff1a;创建项目目录结构、安装必要依赖包…

WebSocket类明明注入了Bean,为什么报错为null

在 WebSocket 类中注入 Bean 看似可行而注入 Bean 报错为null&#xff0c;通常是由于Spring 的单例管理机制与 WebSocket 多实例创建特性冲突导致的&#xff0c;具体分析如下&#xff1a;原因分析Spring 的单例特性&#xff1a;Spring 默认以单例模式管理 Bean&#xff0c;即一…

Python 爬虫开发指南:从基础到实战

在大数据时代&#xff0c;数据成为了宝贵的资源。Python 爬虫作为高效获取网络数据的工具&#xff0c;受到越来越多开发者的关注。本文将详细介绍 Python 爬虫的相关知识&#xff0c;助你快速入门并掌握爬虫开发的核心要点。 一、Python 爬虫概述 Python 爬虫&#xff0c;即网…