Mybatis foreach collection详解

一、forEach collection的基本使用

在Mybatis中,forEach可以用来循环遍历一个集合(collection)或数组(array)的元素,用于动态生成SQL语句。

最常用的forEach 写法如下所示:

<select id="queryByList" resultType="com.example.demo.model.User">
    select * from user
      where id in
    <foreach collection="list" open="(" close=")" item="item" separator=",">
        #{item}
    </foreach>
</select>

解释:

在这个例子中,list是从Java代码中传递过来的 List<Integer> 集合,其里面包含了这个查询需要查的ID(不能是Long,否则如果条件里面是id,则会报类型不匹配),然后在 SQL语句中,将list的内容动态生成一个查询条件。

如果list里面只有一个元素,那么该SQL会被渲染成:

select * from user where id in (1)

如果list里面有两个及以上的元素,那么该SQL会被渲染成:

select * from user where id in (1, 2)

二、collection里面是Map的处理

当我们有一个Map<String, Integer>作为输入参数的时候,forEach的写法如下:

    <select id="queryByMap" resultType="com.example.demo.model.User">
        select * from user
        where id in
        <foreach collection="map" index="key" item="value" open="(" close=")" separator=",">
        #{value}
        </foreach>
    </select>

解释:

map 是从Java代码中传递过来的 Map<String, Integer> 集合,其里面包含了这个查询需要查的ID(不能是Long,否则如果条件里面是id,则会报类型不匹配),其中key是map的键,value是map的值,在SQL语句中,将Map的值动态生成一个查询条件。比如这样实现,则只会查询出ID为 1 和 3的这两条数据。

List<User> list = userDao.queryByMap(new HashMap<String, Integer>() {{
    put("A", 1);
    put("B", 2);
    put("C", 3);
}});

三、基于collection的动态SQL

假设我们有这样的一种需求:当map这个参数中的key值为这五个关键字的时候,就需要暂停一下这个SQL的执行,同时输出一段 SQL 提示语句。

要实现这个目标,可以像下面这样:

    <select id="queryByMap" resultType="com.example.demo.model.User">
        select * from user
        where id in
        <foreach collection="map" index="key" item="value" open="(" close=")" separator=",">
            <if test="'A,B,C,D,E'.indexOf(key)>=0">
                <bind name="sql" value="'select \'These are not allowed!\'; '"/>
            </if>
            #{value}
        </foreach>
        ${sql}
    </select>

解释:

这样写会把 SQL 脚本渲染成

select * from user where id in (
  select 'These are not allowed!';
  1, 2, 3, 4, 5
)

注意:这里的sql是一个绑定,他会被生效,然后其结果也会再次渲染在结果中。

四、动态SQL语句的顺序结构

假设有这样一个查询场景:能够动态选择一个或多个数据库名字,查询名字以某个子串开头的玩家列表。当然,数据库表和字段名、字段值也都可以是参数传递进去。

假如是这样的代码:

<select id="queryByName" resultType="com.example.demo.model.User">
  select * from user
  <where>
    <if test="dbNames != null">
      <foreach collection="dbNames" index="index" item="dbName">
        <if test="index == 0">
          (dbName=#{dbName}
        </if>
        <if test="index > 0">
          or dbName=#{dbName}
        </if>
        <if test="index == dbNames.size()-1">
          )
        </if>
      </foreach>
      and
    </if>
    userName LIKE #{name}%
  </where>
</select>

解释:

上述代码中,语句的先后顺序是先处理 dbName,再处理 userName,再处理dbTable、fieldNames和fieldValues。

五、foreach和bind的扩展

一个数据库表的往往会有很多个字段,如果写在SQL中会显得有些冗长,所以可以用<bind>标签来进行简化。

下面是一个具体的例子。 假设有一个 User 表,需要可以动态地修改这个表的若干个字段名字值,那么这种参数传递的方式需要使用“标记与携带参数(tag and baggage)”方式,即将每个字段名用一个字串标记,并且把每个需要设置的字段的值都放到集合里面:

    <update id="update" parameterType="java.util.Map">
        update user
        <set>
            <foreach collection="fieldNames" index="index" item="field">
                <if test="fieldValues[index] != null">
                    <bind name="x" value="'#{field}' = #{fieldValues[index]}'"/>
                    ${x},${sql}
                </if>
            </foreach>
            updated_at=now()
        </set>
        where id=#{id}
    </update>

解释:

上述代码中,将 注入的SQL 语句的名字放到了一个列表里面,然后再在 foreach 循环中把实际值赋给其中每个项。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/241765.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-12 12:43
下一篇 2024-12-12 12:43

相关推荐

  • 理解Mybatis中的SQL Limit用法

    Mybatis是一种非常流行的ORM框架,提供了SQL映射配置文件,可以使用类似于传统SQL语言的方式编写SQL语句。其中,SQL的Limit语法是一个非常重要的知识点,能够实现分…

    编程 2025-04-29
  • 使用PHP foreach遍历有相同属性的值

    本篇文章将介绍如何使用PHP foreach遍历具有相同属性的值,并给出相应的代码示例。 一、基础概念 在讲解如何使用PHP foreach遍历有相同属性的值之前,我们需要先了解几…

    编程 2025-04-28
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • nginx与apache应用开发详解

    一、概述 nginx和apache都是常见的web服务器。nginx是一个高性能的反向代理web服务器,将负载均衡和缓存集成在了一起,可以动静分离。apache是一个可扩展的web…

    编程 2025-04-25
  • 详解eclipse设置

    一、安装与基础设置 1、下载eclipse并进行安装。 2、打开eclipse,选择对应的工作空间路径。 File -> Switch Workspace -> [选择…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25
  • Python输入输出详解

    一、文件读写 Python中文件的读写操作是必不可少的基本技能之一。读写文件分别使用open()函数中的’r’和’w’参数,读取文件…

    编程 2025-04-25
  • git config user.name的详解

    一、为什么要使用git config user.name? git是一个非常流行的分布式版本控制系统,很多程序员都会用到它。在使用git commit提交代码时,需要记录commi…

    编程 2025-04-25
  • Python安装OS库详解

    一、OS简介 OS库是Python标准库的一部分,它提供了跨平台的操作系统功能,使得Python可以进行文件操作、进程管理、环境变量读取等系统级操作。 OS库中包含了大量的文件和目…

    编程 2025-04-25

发表回复

登录后才能评论