• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

奋斗的软件工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

MyBatis 动态 SQL:<choose> 与 <if>的优雅实践

MyBatis 动态 SQL:<choose> 与 <if> 的优雅实践

在实际开发中,我们经常需要根据不同的条件动态生成 SQL 查询语句。MyBatis 提供了强大的动态 SQL 功能,能够帮助我们轻松实现这一需求。本文将结合一个实际案例,详细讲解如何使用 MyBatis 的 <choose> 和 <if> 标签来实现多条件查询,并分析它们的适用场景和优缺点。


需求描述

我们需要编写一个查询方法,根据以下条件查询所有男性用户:

  1. 如果输入了用户名,则按照用户名模糊查找。
  2. 如果没有输入用户名但输入了住址,则按照住址精确查找。
  3. 如果既没有输入用户名也没有输入住址,则查找用户名为“孙悟空”的用户。

此外,查询条件之间是互斥的,即只能有一个条件生效。


实现方案

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>

代码解析

  1. <choose> 标签

    • 用于包裹多个 <when> 和一个 <otherwise> 分支。
    • 只会执行第一个满足条件的 <when> 分支,后续分支不会执行。
  2. <when> 标签

    • 每个 <when> 对应一个条件分支。
    • test 属性用于指定条件表达式。
  3. <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>

代码解析

  1. <if> 标签

    • 每个 <if> 独立判断条件,如果满足则拼接对应的 SQL 片段。
  2. 条件表达式

    • 通过 test 属性指定条件表达式。
    • 需要显式处理默认逻辑。

优点

  • 灵活,适合处理独立的、非互斥的条件。

缺点

  • 当条件之间存在互斥关系时,逻辑可能变得复杂。
  • 需要显式处理默认逻辑。

适用场景

  • 当条件之间没有互斥关系时。
  • 当需要处理多个独立条件时。

<choose> 与 <if> 的对比

特性 <choose>、<when>、<otherwise> <if>
适用场景 多分支条件,且条件之间互斥 独立的条件判断
默认逻辑 通过 <otherwise> 直接处理 需要显式处理
条件关系 条件之间互斥,只会执行第一个满足的分支 条件之间可以独立,也可以有依赖关系
代码复杂度 逻辑清晰,代码简洁 条件较多时,代码可能冗长

最佳实践

  1. 简单条件判断

    • 使用 <if> 标签,适合处理独立的、非互斥的条件。
  2. 多分支条件判断

    • 使用 <choose>、<when>、<otherwise>,适合处理互斥的多分支条件。
  3. 默认逻辑处理

    • 如果需要默认逻辑,优先使用 <otherwise>,而不是通过多个 <if> 实现。
  4. 动态 WHERE 子句

    • 结合 <where> 标签,避免手动处理 WHERE 子句的多余 AND 或 OR。

总结

MyBatis 的动态 SQL 功能非常强大,能够帮助我们轻松实现复杂的查询逻辑。通过合理使用 <choose> 和 <if> 标签,可以使代码更清晰、更易维护。在实际开发中,应根据具体需求选择合适的动态 SQL 标签,以提高代码的可读性和可维护性。

希望本文对你理解 MyBatis 动态 SQL 有所帮助!如果你有任何问题或建议,欢迎留言讨论!


作者:周政然
日期:2024年1月4日
版权声明:本文为原创文章,转载请注明出处!


如果你觉得这篇文章对你有帮助,欢迎点赞、分享和关注!

posted on 2025-01-04 17:24  周政然  阅读(451)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3