• MyBatis系统学习(三)——动态SQL


    MyBatis 是一款优秀的持久层框架,它通过 XML 或注解方式将 SQL 语句与 Java 对象映射起来。动态 SQL 是 MyBatis 中非常强大的功能之一,能够根据不同的条件动态生成 SQL 语句。动态 SQL 通过各种标签来灵活生成 SQL,从而避免了在代码中拼接 SQL 的复杂性和冗余性。接下来,我们会详细讲解 MyBatis 中动态 SQL 的相关知识点,涵盖动态 SQL 的元素、条件查询、更新操作及复杂查询操作。

    一、MyBatis 动态 SQL 标签

    动态 SQL 主要通过 MyBatis 提供的一些 XML 元素来实现,这些元素会根据传递的参数、条件等动态拼装 SQL。主要的动态 SQL 元素有:

    1. 标签

      • 用于判断条件,只有当条件成立时,才会生成相应的 SQL 片段。
      • 语法:
        <if test="条件">
           SQL 语句
        if>
        
      • 示例:
        <select id="findUser" parameterType="int" resultType="User">
          SELECT * FROM user
          WHERE 1=1
          <if test="id != null">
            AND id = #{id}
          if>
        select>
        
        上述 SQL 语句中,只有当 id 不为 null 时,才会拼接 AND id = #{id} 这部分 SQL。
    2. , , 标签

      • 类似于 Java 中的 switch-case 语法,用于多条件选择。 标签包含若干 ,如果多个 条件都不满足,可以用 作为默认的条件。
      • 语法:
        <choose>
          <when test="条件1">
            SQL 语句1
          when>
          <when test="条件2">
            SQL 语句2
          when>
          <otherwise>
            默认 SQL 语句
          otherwise>
        choose>
        
      • 示例:
        <select id="findUser" parameterType="map" resultType="User">
          SELECT * FROM user
          <where>
            <choose>
              <when test="name != null">
                name = #{name}
              when>
              <when test="age != null">
                age = #{age}
              when>
              <otherwise>
                status = 'active'
              otherwise>
            choose>
          where>
        select>
        
    3. 标签

      • 用来自动处理 WHERE 子句前缀问题。 会智能地在第一个条件前添加 WHERE,并自动去掉多余的 ANDOR
      • 示例:
        <select id="findUser" parameterType="map" resultType="User">
          SELECT * FROM user
          <where>
            <if test="name != null">
              AND name = #{name}
            if>
            <if test="age != null">
              AND age = #{age}
            if>
          where>
        select>
        
        这里,如果 nameage 都为空, 标签会避免生成无效的 WHERE 子句。
    4. 标签

      • 在更新操作中常用,类似于 也会自动处理 SET 关键字前后的逗号问题。
      • 示例:
        <update id="updateUser" parameterType="User">
          UPDATE user
          <set>
            <if test="name != null">
              name = #{name},
            if>
            <if test="age != null">
              age = #{age},
            if>
          set>
          WHERE id = #{id}
        update>
        
        在生成 SQL 时, 标签会自动处理最后一项的逗号。
    5. 标签

      • trim 标签用于自定义去掉前后多余的字符,替代 whereset 标签。它有四个重要的属性:
        • prefix: SQL 片段的前缀,如 WHERESET
        • prefixOverrides: 需要去掉的前缀,如 ANDOR
        • suffix: SQL 片段的后缀。
        • suffixOverrides: 需要去掉的后缀,如 ,
      • 示例:
        <select id="findUser" parameterType="map" resultType="User">
          SELECT * FROM user
          <trim prefix="WHERE" prefixOverrides="AND">
            <if test="name != null">
              AND name = #{name}
            if>
            <if test="age != null">
              AND age = #{age}
            if>
          trim>
        select>
        
    6. 标签

      • 用于处理集合类型的参数,比如 List数组,通常用于 IN 查询或批量插入操作。
      • 重要属性:
        • collection: 要遍历的集合,通常是 ListArray
        • item: 当前集合元素的别名。
        • separator: 元素之间的分隔符,如 ,
        • openclose: 分别表示 SQL 片段的开头和结尾字符。
      • 示例:
        <select id="findUserByIds" parameterType="list" resultType="User">
          SELECT * FROM user
          WHERE id IN
          <foreach collection="list" item="id" open="(" separator="," close=")">
            #{id}
          foreach>
        select>
        

    二、条件查询的使用

    在实际开发中,条件查询是非常常见的需求。MyBatis 中利用动态 SQL 能够灵活生成条件查询语句,通常使用 标签来控制条件的生成。

    示例:简单条件查询
    <select id="findUserByCondition" parameterType="User" resultType="User">
      SELECT * FROM user
      <where>
        <if test="name != null">
          AND name = #{name}
        if>
        <if test="age != null">
          AND age = #{age}
        if>
      where>
    select>
    

    在上面的例子中,只有当 nameage 不为空时,才会生成对应的条件。这样可以避免生成无效的 SQL,提升查询效率。

    示例:多条件选择查询
    <select id="findUserByCondition" parameterType="User" resultType="User">
      SELECT * FROM user
      <where>
        <choose>
          <when test="name != null">
            name = #{name}
          when>
          <when test="age != null">
            age = #{age}
          when>
          <otherwise>
            status = 'active'
          otherwise>
        choose>
      where>
    select>
    

    这个例子中,choose 标签确保只有一个条件成立时才会生成对应的 SQL。如果多个条件不成立,则使用 otherwise 语句。

    三、动态更新操作

    动态 SQL 在更新操作中也非常有用。通常,我们在更新时会根据实际情况只更新某些字段,而不是全部字段。MyBatis 提供了 标签来方便地生成动态更新语句。

    示例:动态更新用户信息
    <update id="updateUser" parameterType="User">
      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>
    

    在这个例子中,只有不为空的字段才会被更新, 标签确保了 SQL 语句中不会出现多余的逗号。

    四、复杂查询操作

    在复杂查询中,动态 SQL 的优势更为明显。我们可以根据多种条件动态生成查询语句,并使用 join、子查询等进行复杂操作。

    示例:动态查询用户及其订单
    <select id="findUserWithOrders" resultMap="userOrderMap">
      SELECT u.*, o.*
      FROM user u
      LEFT JOIN orders o ON u.id = o.user_id
      <where>
        <if test="u.name != null">
          u.name = #{u.name}
        if>
        <if test="o.status != null">
          AND o.status = #{o.status}
        if>
      where>
    select>
    

    这个查询会根据用户信息和订单状态动态生成 SQL,可以方便地查询用户及其订单。

    五、总结

    MyBatis 的动态 SQL 为开发者提供了灵活、可扩展的 SQL 生成方式。通过使用 等标签,能够根据条件动态生成 SQL,简化了代码,避免了 SQL 拼接的复杂性和冗余性。

    动态 SQL 的优势在于:

    • 简化 SQL 编写:开发者可以通过 XML 或注解方式编写复杂的 SQL 逻辑。
    • 提升代码可读性:通过清晰的条件控制和 SQL 生成逻辑,代码更加清晰。
    • 减少代码冗余:避免了在 Java 代码中拼接 SQL 字符串的繁琐操作。

    掌握动态 SQL 的使用对于 MyBatis 框架的实际应用非常重要,在复杂的业务逻辑中尤为常见。

  • 相关阅读:
    rhcsa安装及配置
    usb学习笔记
    【Android】依赖问题
    Java设计模式之单例模式
    bootstrap.properties中配置Nacos
    聊天室(二)__ unipush 推送实现详细教程
    JavaWeb中篇Filter-Transaction-Listener笔记
    WebGL的室内设计软件
    【数据结构初阶】--- 栈和队列
    「设计模式」六大原则之六:最小知识原则小结
  • 原文地址:https://blog.csdn.net/2301_79858914/article/details/142282686