Mybatis的动态sql

1. 前置基础: <if> 标签

大多数动态标签都需要结合 <if> 进行条件判断。

java 复制代码
<if test="name != null and name != ''">
    AND name = #{name}
</if>

2. <where> 标签:智能处理 AND/OR 与 WHERE 关键字

作用

用于封装查询条件。

  • 自动插入 WHERE 关键字(如果内部有满足条件的内容)。

  • 智能去除 内部 SQL 语句开头多余的 ANDOR

java 复制代码
<select id="findUser" resultType="User">
    select * from user
    <where>
        <if test="name != null">
            name = #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

3. <set> 标签:智能处理逗号与 SET 关键字

作用

用于更新操作。

  • 自动插入 SET 关键字。

  • 智能去除 最后一个字段后面多余的逗号 ,

场景:避免更新语句多余的逗号

java 复制代码
<update id="updateUser">
    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>

4. <foreach> 标签:遍历集合(批量操作/IN 查询)

作用

用于遍历数组、List、Map 等集合,通常用于 IN 查询或批量插入。

属性说明

属性 描述
collection 遍历的集合名称(传入的 List/Array/Map 的 Key)
item 当前遍历元素的别名
index 当前索引(List 中是索引,Map 中是 Key)
open 遍历开始拼接的符号(通常是 (
close 遍历结束拼接的符号(通常是 )
separator 元素之间的分隔符(通常是 ,

in条件查询:

java 复制代码
<select id="selectByIds" resultType="User">
    select * from user
    <where>
        id IN
        <foreach collection="list" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </where>
</select>

批量插入

java 复制代码
<insert id="batchInsert">
    insert into user (name, age) values
    <foreach collection="list" item="item" separator=",">
        (#{item.name}, #{item.age})
    </foreach>
</insert>
  • 当遍历 List 或数组时,index 的类型是 int;遍历 Map 时,index 的类型是 Object(与键的类型一致)。
在批量插入中,利用 index 给每个元素加上序号(如生成复合键)
java 复制代码
<insert id="batchInsertWithOrder">
    insert into user_order (user_id, order_seq, product_name) values
    <foreach collection="list" item="item" index="idx" separator=",">
        (#{item.userId}, #{idx}, #{item.productName})
    </foreach>
</insert>

假设传入的 list 包含三个订单项,生成的 SQL 大致为:

java 复制代码
insert into user_order (user_id, order_seq, product_name) values 
(100, 0, '手机'),
(100, 1, '充电器'),
(100, 2, '耳机')
遍历 Map 时,index 取出键(Key)item :表示 Map 中每个键值对的 值(Value)
java 复制代码
<select id="selectByMap" resultType="User">
    select * from user where
    <foreach collection="params" item="value" index="key" separator="AND">
        ${key} = #{value}
    </foreach>
</select>

如果 params 是一个 Map:{"name": "张三", "age": 25},生成的 SQL 是

java 复制代码
select * from user where name = ? AND age = ?

5. <trim> 标签:万能前缀/后缀处理器

<where><set> 本质上是 <trim> 的特殊实现。如果遇到更复杂的拼接需求,可以直接使用 <trim>

属性说明

  • prefix:在 SQL 片段前面加上指定内容。

  • suffix:在 SQL 片段后面加上指定内容。

  • prefixOverrides:去掉 SQL 片段前面指定的多余内容。

  • suffixOverrides:去掉 SQL 片段后面指定的多余内容。

模拟 <where> 标签

java 复制代码
<trim prefix="WHERE" prefixOverrides="AND |OR ">
    ...
</trim>

自定义场景:拼接 values 时去除括号前的逗号

java 复制代码
<trim prefix="(" suffix=")" suffixOverrides=",">
    <if test="name != null">name,</if>
    <if test="age != null">age,</if>
</trim>

6. <choose> (when/otherwise) :类似 Switch 语句

当需要"多选一"的逻辑时使用(只要第一个满足条件的,后面的忽略)。

java 复制代码
<select id="findActiveUser" resultType="User">
    select * from user
    <where>
        <choose>
            <when test="name != null">
                AND name = #{name}
            </when>
            <when test="age != null">
                AND age = #{age}
            </when>
            <otherwise>
                AND status = 'ACTIVE'
            </otherwise>
        </choose>
    </where>
</select>

7. <bind> :绑定变量

用于模糊查询,防止 SQL 注入,或复用变量表达式。

java 复制代码
<select id="selectUser" resultType="User">
    <bind name="pattern" value="'%' + name + '%'"/>
    select * from user where name like #{pattern}
</select>
相关推荐
花月C2 小时前
基于WebSocket的 “聊天” 业务设计与实战指南
java·网络·后端·websocket·网络协议
hongtianzai2 小时前
Laravel7.x十大核心特性解析
java·c语言·开发语言·golang·php
计算机学姐2 小时前
基于SpringBoot的校园二手交易系统
java·vue.js·spring boot·后端·spring·tomcat·intellij-idea
夕珩2 小时前
Java 排序算法详解:冒泡排序、选择排序、堆排序
java·算法·排序算法
勇者无畏4042 小时前
基于 Spring AI Alibaba 搭建 Text-To-SQL 智能系统(简单实现)
数据库·sql
952362 小时前
初识多线程
java·开发语言·jvm·后端·学习·多线程
hongtianzai2 小时前
Laravel9.X核心特性全解析
android·java·数据库
小陈工2 小时前
2026年3月22日技术资讯洞察:数据库优化进入预测时代,网络安全威胁全面升级
java·开发语言·数据库·python·安全·web安全·django
小胖java2 小时前
养老院管理系统
java·spring boot