MyBatis trim标签核心用法代码实战

 更新时间:2026年03月09日 09:52:04   作者:老赵全栈实战  
MyBatis的<trim>标签用于动态SQL拼接,处理SQL前后缀和多余关键字,避免语法错误,提升代码可维护性,本文给大家介绍MyBatis trim标签核心用法代码实战,感兴趣的朋友跟随小编一起看看吧

📅 今日知识点

  • 核心主题:MyBatis<trim>标签基本使用、动态SQL拼接、WHERE条件优化
  • 适用场景:动态查询条件构建、批量更新语句、灵活的SQL片段组装
  • 一句话总结<trim>标签智能处理SQL前后缀和多余关键字,让动态SQL更优雅、更可靠

🧩 核心原理(简化版)

  • <trim>标签通过配置前缀、后缀、去除关键字,自动处理动态SQ 的拼接逻辑
  • 核心逻辑:根据标签内容是否为空,智能添加或删除指定的SQL片段
  • 核心价值:替代手动拼接SQL,避免语法错误(如多余的AND、OR、SET),提升代码可维护性

💻 代码实战(可直接复制运行)

1. 环境配置

<!-- Maven依赖(Spring Boot项目默认包含) -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.0</version>
</dependency>
<!-- 或使用 MyBatis Plus(兼容原生 MyBatis) -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3</version>
</dependency>

2. 核心用法示例

示例一:动态 WHERE 条件查询

// 实体类
@Data
public class User {
    private Long id;
    private String username;
    private String email;
    private Integer age;
    private Integer status;
}
<!-- Mapper XML文件 -->
<mapper namespace="com.example.mapper.UserMapper">
    <!-- 基础结果映射 -->
    <resultMap id="BaseResultMap" type="com.example.entity.User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="email" property="email"/>
        <result column="age" property="age"/>
        <result column="status" property="status"/>
    </resultMap>
    <!-- 动态查询:使用 trim 处理 WHERE 条件 -->
    <select id="selectByCondition" parameterType="com.example.entity.User" resultMap="BaseResultMap">
        SELECT * FROM user
        <trim prefix="WHERE" prefixOverrides="AND|OR">
            <!-- 如果 username 不为空,添加条件 -->
            <if test="username != null and username != ''">
                AND username LIKE CONCAT('%', #{username}, '%')
            </if>
            <!-- 如果 email 不为空,添加条件 -->
            <if test="email != null and email != ''">
                AND email = #{email}
            </if>
            <!-- 如果 age 不为空,添加条件 -->
            <if test="age != null">
                AND age > #{age}
            </if>
            <!-- 如果status不为空,添加条件 -->
            <if test="status != null">
                AND status = #{status}
            </if>
        </trim>
        ORDER BY id DESC
    </select>
</mapper>
// Mapper接口
@Mapper
public interface UserMapper {
    List<User> selectByCondition(@Param("user") User user);
}
// 测试代码
@SpringBootTest
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void testSelectByCondition() {
        // 测试1:只有 username 条件
        User condition1 = new User();
        condition1.setUsername("john");
        List<User> result1 = userMapper.selectByCondition(condition1);
        System.out.println("查询结果1: " + result1.size());
        // 测试2:多个条件组合
        User condition2 = new User();
        condition2.setUsername("alice");
        condition2.setAge(18);
        condition2.setStatus(1);
        List<User> result2 = userMapper.selectByCondition(condition2);
        System.out.println("查询结果2: " + result2.size());
        // 测试3:无条件(返回所有)
        User condition3 = new User();
        List<User> result3 = userMapper.selectByCondition(condition3);
        System.out.println("查询结果3: " + result3.size());
    }
}

生成的SQL示例

-- 测试1:只有 username 条件(自动去除开头的 AND)
SELECT * FROM user
WHERE username LIKE CONCAT('%', 'john', '%')
ORDER BY id DESC
-- 测试2:多个条件组合
SELECT * FROM user
WHERE username LIKE CONCAT('%', 'alice', '%')
  AND age > 18
  AND status = 1
ORDER BY id DESC
-- 测试3:无条件(不生成 WHERE 子句)
SELECT * FROM user
ORDER BY id DESC

示例二:动态 UPDATE 语句

<!-- 动态更新:使用 trim 处理 SET 关键字 -->
<update id="updateSelective" parameterType="com.example.entity.User">
    UPDATE user
    <trim prefix="SET" suffixOverrides=",">
        <if test="username != null and username != ''">
            username = #{username},
        </if>
        <if test="email != null and email != ''">
            email = #{email},
        </if>
        <if test="age != null">
            age = #{age},
        </if>
        <if test="status != null">
            status = #{status},
        </if>
    </trim>
    WHERE id = #{id}
</update>
// 测试代码
@Test
public void testUpdateSelective() {
    // 准备数据
    User user = new User();
    user.setId(1L);
    user.setUsername("updated_user");
    user.setEmail("new@example.com");
    // 只更新 username 和 email,age 和 status 保持不变
    int rows = userMapper.updateSelective(user);
    System.out.println("更新行数:" + rows);
}

生成的SQL示例

-- 只更新非空字段(自动去除末尾的逗号)
UPDATE user
SET username = 'updated_user',
    email = 'new@example.com'
WHERE id = 1

3. trim标签属性详解(4个核心,记牢即可)

<!-- 1. prefix:在trim标签内容前添加的前缀 -->
<trim prefix="WHERE">
    <!-- 内容 -->
</trim>
<!-- 生成:WHERE (内容) -->
<!-- 2. suffix:在 trim 标签内容后添加的后缀 -->
<trim suffix="ORDER BY id">
    <!-- 内容 -->
</trim>
<!-- 生成:(内容) ORDER BY id -->
<!-- 3. prefixOverrides:要去除的前缀(支持正则表达式,用 | 分隔) -->
<trim prefix="WHERE" prefixOverrides="AND|OR">
    <if test="condition1">AND col1 = val1</if>
    <if test="condition2">AND col2 = val2</if>
</trim>
<!-- 生成:WHERE col1 = val1 AND col2 = val2 -->
<!-- 4. suffixOverrides:要去除的后缀(支持正则表达式,用 | 分隔) -->
<trim prefix="SET" suffixOverrides=",">
    <if test="col1 != null">col1 = val1,</if>
    <if test="col2 != null">col2 = val2,</if>
</trim>
<!-- 生成:SET col1 = val1, col2 = val2 -->

⚠️ 避坑指南(简洁重点)

1.核心坑1:prefixOverrides未正确配置导致SQL语法错误

<!-- ❌ 错误写法:忘记配置 prefixOverrides -->
<select id="selectBad" resultMap="BaseResultMap">
    SELECT * FROM user
    <trim prefix="WHERE">
        <if test="username != null">
            AND username = #{username}  <!-- 第一个条件前有 AND -->
        </if>
    </trim>
</select>
<!-- 生成错误SQL:SELECT * FROM user WHERE AND username = ? -->
<!-- ✅ 正确写法:配置 prefixOverrides="AND|OR" -->
<select id="selectGood" resultMap="BaseResultMap">
    SELECT * FROM user
    <trim prefix="WHERE" prefixOverrides="AND|OR">
        <if test="username != null">
            AND username = #{username}
        </if>
    </trim>
</select>
<!-- 生成正确SQL:SELECT * FROM user WHERE username = ? -->

2.核心坑2:suffixOverrides未去除多余逗号

<!-- ❌ 错误写法:忘记配置 suffixOverrides -->
<update id="updateBad">
    UPDATE user
    <trim prefix="SET">
        <if test="username != null">
            username = #{username},  <!-- 最后一个字段后有逗号 -->
        </if>
    </trim>
    WHERE id = #{id}
</update>
<!-- 生成错误SQL:UPDATE user SET username = ?, -->
<!-- ✅ 正确写法:配置 suffixOverrides="," -->
<update id="updateGood">
    UPDATE user
    <trim prefix="SET" suffixOverrides=",">
        <if test="username != null">
            username = #{username},
        </if>
    </trim>
    WHERE id = #{id}
</update>
<!-- 生成正确SQL:UPDATE user SET username = ? WHERE id = ? -->

3.核心坑3:trim嵌套使用时的注意事项

<!-- ✅ 复杂场景:trim 可以嵌套使用 -->
<select id="selectComplex" resultMap="BaseResultMap">
    SELECT * FROM user
    <trim prefix="WHERE" prefixOverrides="AND|OR">
        <!-- 外层 trim 处理 WHERE -->
        <if test="query != null">
            <!-- 内层 trim 处理分组条件 -->
            <trim prefix="(" prefixOverrides="AND|OR" suffix=")">
                <if test="query.username != null">
                    AND username LIKE #{query.username}
                </if>
                <if test="query.email != null">
                    AND email LIKE #{query.email}
                </if>
            </trim>
        </if>
        <if test="status != null">
            AND status = #{status}
        </if>
    </trim>
</select>
<!-- 生成SQL:SELECT * FROM user WHERE (username LIKE ? AND email LIKE ?) AND status = ? -->

4.核心坑4:trim vs where/set标签选择

<!-- trim 标签:最灵活,可自定义前后缀和去除规则 -->
<trim prefix="WHERE" prefixOverrides="AND|OR" suffix="LIMIT 10">
    <!-- 复杂场景 -->
</trim>
<!-- where 标签:trim的简化版,固定处理WHERE和AND/OR -->
<where>
    <if test="condition1">AND col1 = val1</if>
    <if test="condition2">AND col2 = val2</if>
</where>
<!-- 等价于:<trim prefix="WHERE" prefixOverrides="AND|OR"> -->
<!-- set 标签:trim的简化版,固定处理SET和逗号 -->
<set>
    <if test="col1 != null">col1 = val1,</if>
    <if test="col2 != null">col2 = val2,</if>
</set>
<!-- 等价于:<trim prefix="SET" suffixOverrides=","> -->
<!-- 最佳实践:简单场景用 where/set,复杂场景用 trim -->

✅ 今日总结

  • <trim>标签核心是"智能拼接",自动处理 SQL 前后缀和多余关键字,避免语法错误
  • 4个核心属性:prefix(前缀)、suffix(后缀)、prefixOverrides(去前缀)、suffixOverrides(去后缀)
  • 实用性强:动态查询、批量更新、复杂条件组装等场景都能大幅提升 SQL 可维护性
  • 最佳实践:简单场景用 <where>/<set>简化版,复杂场景用 <trim>完整版

到此这篇关于MyBatis trim标签核心用法代码实战的文章就介绍到这了,更多相关MyBatis trim标签用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于springboot2.4跨域配置问题

    关于springboot2.4跨域配置问题

    这篇文章主要介绍了springboot2.4跨域配置的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • springboot打包无法读取yml、properties等配置文件的解决

    springboot打包无法读取yml、properties等配置文件的解决

    这篇文章主要介绍了springboot打包无法读取yml、properties等配置文件的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • Spring Cloud 中使用 Sentinel 实现服务限流的两种方式

    Spring Cloud 中使用 Sentinel 实现服务限流的两种方式

    这篇文章主要介绍了Spring Cloud 中使用 Sentinel 实现服务限流的方式,通过示例代码主要介绍了Sentinel的两种实现限流的方式,需要的朋友可以参考下
    2024-03-03
  • Java JDK Validation 注解解析与使用方法验证

    Java JDK Validation 注解解析与使用方法验证

    Jakarta Validation提供了一种声明式、标准化的方式来验证Java对象,与框架无关,可以方便地集成到各种Java应用中,本文给大家介绍Java JDK Validation 注解解析与使用,感兴趣的朋友一起看看吧
    2025-09-09
  • BeanUtils.copyProperties复制对象结果为空的原因分析

    BeanUtils.copyProperties复制对象结果为空的原因分析

    这篇文章主要介绍了BeanUtils.copyProperties复制对象结果为空的原因分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java利用多线程复制文件

    Java利用多线程复制文件

    这篇文章主要介绍了Java利用多线程复制文件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09
  • Java的Lambda表达式使用及说明

    Java的Lambda表达式使用及说明

    文章介绍了JavaSE8中的Lambda表达式,其基本语法、函数接口的概念以及在集合中的使用,同时,还讨论了Lambda表达式的变量捕获和一些优点与缺点
    2026-02-02
  • springboot泛型封装开发方式

    springboot泛型封装开发方式

    这篇文章主要介绍了springboot泛型封装开发方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Idea2023配置tomcat服务器的图文教程

    Idea2023配置tomcat服务器的图文教程

    这篇文章主要介绍了Idea2023配置tomcat服务器的图文教程,本文是javaweb新手版教程,IDEA2023+JDK1.8+apache-tomcat-8.5.91,没有使用Maven,需要的朋友可以参考下
    2023-10-10
  • SpringCloud可视化链路追踪系统Zipkin部署过程

    SpringCloud可视化链路追踪系统Zipkin部署过程

    这篇文章主要介绍了SpringCloud可视化链路追踪系统Zipkin部署过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03

最新评论