MyBatis 动态 SQL:<choose> 与 <if>的优雅实践
MyBatis 动态 SQL:<choose> 与 <if> 的优雅实践
在实际开发中,我们经常需要根据不同的条件动态生成 SQL 查询语句。MyBatis 提供了强大的动态 SQL 功能,能够帮助我们轻松实现这一需求。本文将结合一个实际案例,详细讲解如何使用 MyBatis 的 <choose> 和 <if> 标签来实现多条件查询,并分析它们的适用场景和优缺点。
需求描述
我们需要编写一个查询方法,根据以下条件查询所有男性用户:
- 如果输入了用户名,则按照用户名模糊查找。
- 如果没有输入用户名但输入了住址,则按照住址精确查找。
- 如果既没有输入用户名也没有输入住址,则查找用户名为“孙悟空”的用户。
此外,查询条件之间是互斥的,即只能有一个条件生效。
实现方案
1. 使用 <choose>、<when>、<otherwise> 实现
<choose> 标签类似于 Java 中的 switch-case 结构,适合处理多分支条件。以下是实现代码:
<select id="queryUserByUserNameOrAddressOrGender" resultType="User">
    SELECT * FROM tb_user_v2
    WHERE gender = '男'
    <choose>
        <when test="userName != null and userName.trim() != ''">
            AND userName LIKE CONCAT('%', #{userName}, '%')
        </when>
        <when test="address != null and address.trim() != ''">
            AND address = #{address}
        </when>
        <otherwise>
            AND userName = '孙悟空'
        </otherwise>
    </choose>
</select>
代码解析
- 
<choose>标签- 用于包裹多个 <when>和一个<otherwise>分支。
- 只会执行第一个满足条件的 <when>分支,后续分支不会执行。
 
- 用于包裹多个 
- 
<when>标签- 每个 <when>对应一个条件分支。
- test属性用于指定条件表达式。
 
- 每个 
- 
<otherwise>标签- 当所有 <when>条件都不满足时,执行<otherwise>分支。
 
- 当所有 
优点
- 逻辑清晰,代码简洁。
- 适合处理互斥的多分支条件。
适用场景
- 当条件之间存在互斥关系时(例如,只能有一个条件生效)。
- 当需要明确的默认逻辑时。
2. 使用 <if> 标签实现
<if> 标签用于根据条件动态拼接 SQL 片段。以下是实现代码:
<select id="queryUserByUserNameOrAddressOrGender" resultType="User">
    SELECT * FROM tb_user_v2
    WHERE gender = '男'
    <if test="userName != null and userName.trim() != ''">
        AND userName LIKE CONCAT('%', #{userName}, '%')
    </if>
    <if test="(userName == null or userName.trim() == '') and (address != null and address.trim() != '')">
        AND address = #{address}
    </if>
    <if test="(userName == null or userName.trim() == '') and (address == null or address.trim() == '')">
        AND userName = '孙悟空'
    </if>
</select>
代码解析
- 
<if>标签- 每个 <if>独立判断条件,如果满足则拼接对应的 SQL 片段。
 
- 每个 
- 
条件表达式 - 通过 test属性指定条件表达式。
- 需要显式处理默认逻辑。
 
- 通过 
优点
- 灵活,适合处理独立的、非互斥的条件。
缺点
- 当条件之间存在互斥关系时,逻辑可能变得复杂。
- 需要显式处理默认逻辑。
适用场景
- 当条件之间没有互斥关系时。
- 当需要处理多个独立条件时。
<choose> 与 <if> 的对比
| 特性 | <choose>、<when>、<otherwise> | <if> | 
|---|---|---|
| 适用场景 | 多分支条件,且条件之间互斥 | 独立的条件判断 | 
| 默认逻辑 | 通过 <otherwise>直接处理 | 需要显式处理 | 
| 条件关系 | 条件之间互斥,只会执行第一个满足的分支 | 条件之间可以独立,也可以有依赖关系 | 
| 代码复杂度 | 逻辑清晰,代码简洁 | 条件较多时,代码可能冗长 | 
最佳实践
- 
简单条件判断 - 使用 <if>标签,适合处理独立的、非互斥的条件。
 
- 使用 
- 
多分支条件判断 - 使用 <choose>、<when>、<otherwise>,适合处理互斥的多分支条件。
 
- 使用 
- 
默认逻辑处理 - 如果需要默认逻辑,优先使用 <otherwise>,而不是通过多个<if>实现。
 
- 如果需要默认逻辑,优先使用 
- 
动态 WHERE 子句 - 结合 <where>标签,避免手动处理WHERE子句的多余AND或OR。
 
- 结合 
总结
MyBatis 的动态 SQL 功能非常强大,能够帮助我们轻松实现复杂的查询逻辑。通过合理使用 <choose> 和 <if> 标签,可以使代码更清晰、更易维护。在实际开发中,应根据具体需求选择合适的动态 SQL 标签,以提高代码的可读性和可维护性。
希望本文对你理解 MyBatis 动态 SQL 有所帮助!如果你有任何问题或建议,欢迎留言讨论!
作者:周政然
日期:2024年1月4日
版权声明:本文为原创文章,转载请注明出处!
如果你觉得这篇文章对你有帮助,欢迎点赞、分享和关注!
 
                    
                     
                    
                 
                    
                 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号