JavaWeb——Mybatis-动态SQL(1/3)-if及案例(概述、if 语句的作用、基本用法、语法解析、实际应用,案例介绍、需求分析、现有问题分析、代码改造:使用 if 实现动态更新)

目录

MyBatis 动态 SQL if 条件

概述

if 语句的作用

基本用法

语法解析

实际应用

按姓名和年龄查询员工

复杂条件查询

优势分析

总结

MyBatis 动态 SQL if 案例

案例介绍

需求分析

现有问题分析

代码改造:使用 if 实现动态更新

关键改进点

测试与验证

1.仅更新部分字段

输入

生成的 SQL 语句

2.只更新 username

输入

生成的 SQL 语句

解决的问题

总结


MyBatis 动态 SQL if 条件

概述

        在 MyBatis 中,动态 SQL 允许根据不同的查询条件动态拼接 SQL 语句,提高查询的灵活性,避免手写冗余 SQL 代码。其中,if 语句是最基础也是最常用的一种动态 SQL 语句。

if 语句的作用

   if 语句用于在 SQL 语句中根据传入参数的值决定是否拼接某个 SQL 片段。例如,用户提供的查询条件不同,生成的 SQL 语句也随之变化,以提高查询效率和代码复用性。

基本用法

在 XML 配置文件中,if 语句使用 <if> 标签,通常配合 test 属性进行条件判断。例如:

<select id="findByCondition" resultType="com.qiyi.pojo.Emp">
    SELECT * FROM emp
    WHERE 1=1
    <if test="name != null and name != ''">
        AND name = #{name}
    </if>
    <if test="age != null">
        AND age = #{age}
    </if>
</select>

语法解析

  • test 属性:用于判断是否执行该 SQL 片段。
  • #{}:表示 MyBatis 绑定参数,防止 SQL 注入。
  • WHERE 1=1:避免动态拼接时 AND 关键字导致 SQL 语法错误。
  • <if> 语句逻辑:
    • 仅当 name 不为空且不为空字符串时,拼接 AND name = #{name}
    • 仅当 age 不为空时,拼接 AND age = #{age}

实际应用

按姓名和年龄查询员工

<select id="findByNameAndAge" resultType="com.qiyi.pojo.Emp">
    SELECT * FROM emp
    WHERE 1=1
    <if test="name != null and name != ''">
        AND name = #{name}
    </if>
    <if test="age != null">
        AND age = #{age}
    </if>
</select>

复杂条件查询

<select id="findByConditions" resultType="com.itheima.pojo.Emp">
    SELECT * FROM emp
    WHERE 1=1
    <if test="dept != null">
        AND dept = #{dept}
    </if>
    <if test="salary != null">
        AND salary &gt; #{salary}
    </if>
</select>

这里的   &gt  是一个 XML 实体引用,它代表的是大于符号 >

        在 XML 文档中,像 <>& 这类字符是具有特殊含义的。< 通常用来标识一个标签的开始,& 则用于引入实体引用。如果直接在 XML 里使用这些特殊字符,XML 解析器可能会将其误认成标签或实体引用的起始符号,从而引发解析错误。

优势分析

  • 灵活性:根据输入参数动态拼接 SQL,减少代码冗余。
  • 查询优化:避免无关条件,提高查询效率。
  • 维护性强:比手写多条 SQL 语句更简洁清晰。

总结

MyBatis 的 <if> 语句是动态 SQL 处理的基础,能有效避免冗余代码,提高 SQL 语句的灵活性和可维护性。在实际开发中,合理使用 if 语句可以提高查询效率,使 SQL 更加灵活。

MyBatis 动态 SQL if 案例

案例介绍

        本案例旨在加强对 MyBatis if 标签的理解,并通过 动态更新员工信息 的实际案例,展示 if 标签在 SQL 语句中的灵活应用。

需求分析

在原有的 更新员工 功能中,存在以下问题:

  • 现有 update 方法会 更新所有字段,即使某些字段没有提供新值,导致原数据丢失。
  • 需要改进,使其能够 仅更新传递了新值的字段

目标:实现动态 SQL 更新功能,如果字段值存在,则更新该字段,否则保持原值不变。

现有问题分析

update 方法示例:

<update id="update">
    UPDATE emp
    SET username = #{username}, name = #{name}, gender = #{gender},
        image = #{image}, job = #{job}, entry_date = #{entryDate},
        dept_id = #{deptId}, update_time = NOW()
    WHERE id = #{id};
</update>

问题:

  • username 为空,name 为空,更新后数据库中的字段值将变成 NULL
  • 预期行为应为 只更新传递了新值的字段,不影响未提供数据的字段。

代码改造:使用 if 实现动态更新

改进后的 update 语句:

<update id="updateDynamic">
    UPDATE emp
    <set>
        <if test="username != null">username = #{username},</if>
        <if test="name != null">name = #{name},</if>
        <if test="gender != null">gender = #{gender},</if>
        <if test="image != null">image = #{image},</if>
        <if test="job != null">job = #{job},</if>
        <if test="entrydate != null">entry_date = #{entryDate},</if>
        <if test="deptId != null">dept_id = #{deptId},</if>
        update_time = NOW()
    </set>
    WHERE id = #{id};
</update>

关键改进点

使用 <if> 标签:仅在字段值不为空时拼接 SQL 语句,避免 NULL 赋值。 

使用 <set> 标签

  • 自动添加 SET 关键字。
  • 去除 SQL 语句末尾的多余逗号,防止 SQL 语法错误。

测试与验证

1.仅更新部分字段

输入
Emp emp = new Emp();
emp.setId(18);
emp.setUsername("TOM111");
emp.setName("Tom111");
emp.setGender(2);
empMapper.updateDynamic(emp);
生成的 SQL 语句
UPDATE emp
SET username = 'TOM111', name = 'Tom111', gender = 2, update_time = NOW()
WHERE id = 18;

🔹 仅更新了传递了值的字段,未传递的字段保持原值

2.只更新 username

输入
Emp emp = new Emp();
emp.setId(19);
emp.setUsername("Tom222");
empMapper.updateDynamic(emp);
生成的 SQL 语句
UPDATE emp
SET username = 'Tom222', update_time = NOW()
WHERE id = 19;

🔹 没有多余的逗号,SQL 语法正确

解决的问题

  • 避免 不必要的 NULL 赋值,仅更新需要修改的字段。
  • 解决 静态 SQL 导致的字段数据丢失
  • 使用 <set> 处理 SQL 语法问题,避免多余逗号

总结

  • if 标签 使 SQL 语句动态化,仅在必要时拼接字段。
  • set 标签 处理 UPDATE 语句的 SET 关键字多余逗号问题
  • 动态 SQL 提高了查询的灵活性,有效避免静态 SQL 带来的数据更新问题。

👉 推荐在复杂的更新操作中使用 ifset,确保 SQL 语句的正确性和可维护性!


END 


学习自:黑马程序员——JavaWeb课程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值