Mybatis的动态sql

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

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

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

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

作用

用于封装查询条件。

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

  • 智能去除 内部 SQL 语句开头多余的 AND 或 OR。

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>
相关推荐
开开心心_Every8 小时前
免费压缩软件WinRAR无弹窗、广告干扰
java·开发语言·前端·spring·智能手机·word·winrar
计算机毕设定制辅导-无忧学长8 小时前
《基于微信小程序的个人智能刷题助手的设计与实现》
java·spring boot·mysql·微信小程序·uniapp·个人智能刷题助手系统
geovindu8 小时前
sql:Managing Complex Joins and Subqueries in SQL using mysql 9.0
大数据·数据库·数据仓库·sql·mysql·数据库开发·数据库架构
步行cgn8 小时前
Spring MVC 中实现 request 域效果的几种方式
java·后端
Thomas.Sir8 小时前
第3课:SpringBoot4.x 自动配置原理:@EnableAutoConfiguration底层源码剖析
java·spring boot
Rain的Java大神之路8 小时前
MySQL 被高并发打爆?从定位到分库分表逐层拆解(含秒杀库存实战)
java·后端·面试
cc_瀚海知行8 小时前
工具调用 6|助手什么时候该停下来?
java·服务器·前端·人工智能·python·ai
YDS8298 小时前
Small Spring IOC篇:应用上下文实现和Bean的扩展
java·后端·spring
Pniubi8 小时前
ConcurrentHashMap拆分线程池难点再讲
java·jvm
golang学习记8 小时前
IDEA 的 Java 智能,现在跑到 Cursor 和 VS Code 里去了
java·ide·vscode·intellij-idea·claude code