MyBatis (where、set、foreach)标签

本文介绍了MyBatis框架中的where标签用于简化SQL条件判断,set标签用于动态更新数据库列,以及foreach标签在处理in条件和遍历集合的应用,通过实例展示了如何在代码中使用这些标签。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

where标签

 在上一节SQL 语句中加入了一个条件“1=1”,如果没有加入这个条件,那么可能就会变成下面这样一条错误的语句。

SELECT id,name,url,age,country FROM website AND name LIKE CONCAT('%',#{name},'%')

显然以上语句会出现 SQL 语法异常,但加入“1=1”这样的条件又非常奇怪,所以 MyBatis 提供了 where 标签。
where 标签主要用来简化 SQL 语句中的条件判断,可以自动处理 AND/OR 条件,语法如下

<where>
    <if test="判断条件">
        AND/OR ...
    </if>
</where>

if 语句中判断条件为 true 时,where 关键字才会加入到组装的 SQL 里面,否则就不加入。where 会检索语句,它会将 where 后的第一个 SQL 条件语句的 AND 或者 OR 关键词去掉。

示例:

<select id="selectWebsite" resultType="net.cc.po.Website">
    select id,name,url from website
    <where>
        <if test="name != null">
            AND name like #{name}
        </if>
        <if test="url!= null">
            AND url like #{url}
        </if>
    </where>
</select>

测试

public class Test {
    public static void main(String[] args) throws IOException {
        // 读取配置文件mybatis-config.xml
        InputStream config = Resources.getResourceAsStream("mybatis-config.xml"); // 根据配置文件构建
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
        // 通过SqlSessionFactory创建SqlSession
        SqlSession ss = ssf.openSession();
        Website site = new Website();
        site.setname("编程");
        List<Website> siteList = ss.selectList("net.cc.mapper.WebsiteMapper.selectWebsite", site);
        for (Website ws : siteList) {
            System.out.println(ws);
        }
    }
}

set标签

在 Mybatis 中,update 语句可以使用 set 标签动态更新列。set 标签可以为 SQL 语句动态的添加 set 关键字,剔除追加到条件末尾多余的逗号。

示例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.cc.mapper.WebsiteMapper">
    <select id="selectWebsite" resultType="net.cc.po.Website">
        SELECT * FROM website
        <where>
            <if test="id!=null and id!=''">
                id=#{id}
            </if>
        </where>
    </select>
    <!--使用set元素动态修改一个网站记录 -->
    <update id="updateWebsite"
        parameterType="net.cc.po.Website">
        UPDATE website
        <set>
            <if test="name!=null">name=#{name}</if>
            <if test="url!=null">url=#{url}</if>
        </set>
        WHERE id=#{id}
    </update>
</mapper>

测试

public class Test {
    public static void main(String[] args) throws IOException {
        InputStream config = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
        SqlSession ss = ssf.openSession();
        Website site = new Website();
        site.setId(1);
        site.setUrl("www.cc.net");
        // 执行update语句前
        List<Website> siteList = ss.getMapper(WebsiteMapper.class).selectWebsite(site);
        for (Website st : siteList) {
            System.out.println(st);
        }
        int num = ss.getMapper(WebsiteMapper.class).updateWebsite(site);
        System.out.println("影响数据库行数" + num);
        // 执行update语句后
        List<Website> siteList2 = ss.getMapper(WebsiteMapper.class).selectWebsite(site);
        for (Website st : siteList2) {
            System.out.println(st);
        }
        ss.commit();
        ss.close();
    }
}

foreach标签

对于一些 SQL 语句中含有 in 条件,需要迭代条件集合来生成的情况,可以使用 foreach 来实现 SQL 条件的迭代。 

Mybatis foreach 标签用于循环语句,它很好的支持了数据和 List、set 接口的集合,并对此提供遍历的功能。语法格式如下。

<foreach item="item" index="index" collection="list|array|map key" open="(" separator="," close=")">
    参数值
</foreach>

foreach 标签主要有以下属性,说明如下。

  • item:表示集合中每一个元素进行迭代时的别名。
  • index:指定一个名字,表示在迭代过程中每次迭代到的位置。
  • open:表示该语句以什么开始(既然是 in 条件语句,所以必然以(开始)。
  • separator:表示在每次进行迭代之间以什么符号作为分隔符(既然是 in 条件语句,所以必然以,作为分隔符)。
  • close:表示该语句以什么结束(既然是 in 条件语句,所以必然以)开始)。


使用 foreach 标签时,最关键、最容易出错的是 collection 属性,该属性是必选的,但在不同情况下该属性的值是不一样的,主要有以下 3 种情况:

  • 如果传入的是单参数且参数类型是一个 List,collection 属性值为 list。
  • 如果传入的是单参数且参数类型是一个 array 数组,collection 的属性值为 array。
  • 如果传入的参数是多个,需要把它们封装成一个 Map,当然单参数也可以封装成 Map。Map 的 key 是参数名,collection 属性值是传入的 List 或 array 对象在自己封装的 Map 中的 key。

示例

<select id="selectWebsite"
    parameterType="net.cc.po.Website"
    resultType="net.biancheng.po.Website">
    SELECT id,name,url,age,country
    FROM website WHERE age in
    <foreach item="age" index="index" collection="list" open="("
        separator="," close=")">
        #{age}
    </foreach>
</select>

 测试

public class Test {
    public static void main(String[] args) throws IOException {
        // 读取配置文件mybatis-config.xml
        InputStream config = Resources.getResourceAsStream("mybatis-config.xml"); // 根据配置文件构建
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
        // 通过SqlSessionFactory创建SqlSession
        SqlSession ss = ssf.openSession();
        List<Integer> ageList = new ArrayList<Integer>();
        ageList.add(10);
        ageList.add(12);
        List<Website> siteList = ss.selectList("net.cc.mapper.WebsiteMapper.selectWebsite", ageList);
        for (Website ws : siteList) {
            System.out.println(ws);
        }
    }
}

在使用 foreach 标签时,应提前预估一下 collection 对象的长度。因为大量数据的 in 语句会影响性能,且还有一些数据库会限制执行的 SQL 语句长度。 

### MyBatis 中 `<foreach>` 标签的使用方法 `<foreach>` 是 MyBatis 提供的一个用于处理集合类型参数的动态 SQL 标签,适用于遍历数组、List、Set 等集合结构,并在 SQL 语句中生成多个值或子句。它常用于 `IN` 查询、批量插入、批量更新等场景。 #### 基本语法格式如下: ```xml <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> ``` 其中主要属性说明如下: - `collection`:指定要遍历的集合对象,可以是 List、Map 或数组。 - `item`:集合中每个元素的别名,在循环体内通过 `${item}` 或 `#{item}` 使用。 - `index`:迭代索引,可选,用于获取当前索引值。 - `open` 和 `close`:指定在遍历结果前后添加的内容,如括号 `( ... )`。 - `separator`:每次迭代之间的分隔符,如逗号 `,`。 #### 示例一:`IN` 查询 在查询语句中使用 `<foreach>` 实现 `IN` 条件筛选: ```xml <select id="selectByIds" resultType="Product"> SELECT * FROM product_ WHERE ID IN <foreach item="id" collection="idList" open="(" separator="," close=")"> #{id} </foreach> </select> ``` 该语句将根据传入的 `idList` 集合动态生成 `IN` 子句,适用于多条件匹配查询[^1]。 #### 示例二:批量插入(UNION ALL 方式) 使用 `<foreach>` 可以实现高效的批量插入操作,例如通过 `UNION ALL` 的方式构造多个 `SELECT` 子句: ```xml <insert id="insertBatchUnionAll2" parameterType="list"> INSERT INTO user_info (`user_no`, `name`, `age`) <foreach collection="list" item="e" separator="UNION ALL"> (SELECT #{e.userNo}, #{e.name}, #{e.age} FROM dual) </foreach> </insert> ``` 此方法适用于目标数据库不支持原生批量插入的场景,通过一次执行完成多个记录的插入操作[^2]。 #### 示例三:批量插入(VALUES 方式) 另一种常见的批量插入方式是直接使用 `VALUES` 构造多个插入项: ```xml <insert id="insertBatchValues" parameterType="list"> INSERT INTO user_info (`user_no`, `name`, `age`) VALUES <foreach collection="list" item="e" separator=","> (#{e.userNo}, #{e.name}, #{e.age}) </foreach> </insert> ``` 这种方式更常见于 MySQL、PostgreSQL 等支持多值插入的数据库系统。 #### 示例四:构建动态 SQL 片段 除了数据操作语句,`<foreach>` 还可用于构建复杂的 SQL 条件片段,如与 `<where>`、`<choose>` 等标签结合使用: ```xml <where> <if test="ids != null and ids.size() > 0"> AND id IN <foreach item="id" collection="ids" open="(" separator="," close=")"> #{id} </foreach> </if> </where> ``` 此类结构常用于构建灵活的查询条件逻辑。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值