Mybatis中动态sql的作用

MyBatis 的动态 SQL 是其核心特性之一,通过灵活的标签和表达式,允许开发者根据运行时条件动态生成 SQL 语句。以下是其核心作用及具体应用场景:


一、动态 SQL 的核心作用

  1. 灵活的条件查询
    • 按需拼接 SQL:根据参数是否为空动态添加WHERE条件,避免冗余的AND或OR。

    1

    2

    3

    4

    5

    6

    7

    <select id="findUser" resultType="User">

      SELECT * FROM user

      <where>

        <if test="name != null">AND name = #{name}</if>

        <if test="age != null">AND age = #{age}</if>

      </where>

    </select>

    效果:若name和age均为空,则生成SELECT * FROM user;若仅name有值,则生成WHERE name = ?。

  2. 减少重复代码
    • 避免多条件分支硬编码:通过<choose>/<when>/<otherwise>实现多条件互斥选择,替代多个if-else判断。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    <select id="findUserByType">

      SELECT * FROM user

      WHERE role =

      <choose>

        <when test="role == 'admin'">'ADMIN'</when>

        <when test="role == 'user'">'USER'</when>

        <otherwise>'GUEST'</otherwise>

      </choose>

    </select>

    优势:代码简洁,逻辑清晰,维护成本低。

  3. 动态批量操作
    • 集合遍历生成 SQL:通过<foreach>标签遍历集合,生成IN语句或批量插入。

    1

    2

    3

    4

    5

    6

    <select id="selectByIds">

      SELECT * FROM user WHERE id IN

      <foreach collection="ids" item="id" open="(" separator="," close=")">

        #{id}

      </foreach>

    </select>

    应用场景:批量查询、批量更新或删除。

  4. 防止 SQL 注入
    • 参数化绑定:使用#{}占位符自动转义特殊字符,避免拼接字符串导致的注入风险。

    1

    2

    <bind name="pattern" value="'%' + name + '%'" />

    SELECT * FROM user WHERE name LIKE #{pattern}

    安全性:即使参数含恶意字符(如' OR 1=1 --),也会被转义为普通字符串。

  5. 动态更新与字段控制
    • 按需更新字段:通过<set>标签动态生成UPDATE语句,避免冗余字段和末尾逗号。

    1

    2

    3

    4

    5

    6

    7

    8

    <update id="updateUser">

      UPDATE user

      <set>

        <if test="name != null">name = #{name},</if>

        <if test="age != null">age = #{age},</if>

      </set>

      WHERE id = #{id}

    </update>

    效果:仅更新非空字段,减少数据库写入量。


二、典型应用场景

场景动态 SQL 方案效果
多条件查询<if>+<where>按需生成WHERE子句,避免冗余条件
分页查询<foreach>+ 分页插件动态生成LIMIT和OFFSET
批量插入/更新<foreach>遍历集合单条 SQL 处理多条数据,减少数据库交互
多表关联查询<choose>动态选择关联表根据业务需求切换关联逻辑
动态排序<if>控制ORDER BY字段和方向支持用户自定义排序规则

三、动态 SQL 的执行原理

  1. OGNL 表达式解析:MyBatis 使用 OGNL(Object-Graph Navigation Language)解析动态标签中的条件表达式(如#{name}),将参数映射到 SQL 中。
  2. SqlNode 组合:动态标签被解析为SqlNode对象(如IfSqlNode、WhereSqlNode),通过组合模式构建完整的SqlSource,最终生成可执行的 SQL。
  3. 预编译与参数绑定:生成的 SQL 仍使用PreparedStatement进行参数绑定,确保安全性和性能。

四、实际场景示例

场景:多条件搜索用户

复制代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<select id="searchUsers" resultType="User">

  SELECT * FROM user

  <where>

    <if test="name != null">

      AND name LIKE CONCAT('%', #{name}, '%')

    </if>

    <if test="minAge != null">

      AND age >= #{minAge}

    </if>

    <if test="roles != null and roles.size() > 0">

      AND role IN

      <foreach collection="roles" item="role" open="(" close=")" separator=",">

        #{role}

      </foreach>

    </if>

  </where>

  ORDER BY create_time DESC

</select>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值