当前位置: 首页 > news >正文

动态SQL

<delete id="deleteByEntity" parameterType="com.javapandeng.po.Manage">delete from manage where 1=1<include refid="Manage_where"/></delete>
//在这个代码中,manage只是一个实体类,为什么可以通过它删除

 

这是一个非常好的问题,它触及了 MyBatis 动态 SQL 的一个核心技巧。虽然 Manage 是一个实体类,但这段代码巧妙地利用了它来构建一个灵活的条件删除语句

关键就在于 <include refid="Manage_where"/> 所引用的 Manage_where SQL 片段。这个片段内部使用了 MyBatis 的动态 SQL 标签(如 <if>)。

核心原理:动态 SQL

MyBatis 的强大之处在于它的动态 SQL 能力。它允许你在 XML 中编写“智能”的 SQL 片段,这些片段会根据传入参数的具体值来动态地改变最终生成的 SQL 语句。

Manage_where 片段(虽然没有在你提供的代码中展示,但这是标准做法)通常会像下面这样定义:

xml
<!-- 这是一个假设的 Manage_where 片段定义 -->
<sql id="Manage_where"><if test="id != null">AND id = #{id}</if><if test="userName != null and userName != ''">AND userName = #{userName}</if><if test="passWord != null and passWord != ''">AND passWord = #{passWord}</if><if test="realName != null and realName != ''">AND realName = #{realName}</if>
</sql>

工作流程详解

现在,我们把 deleteByEntity 语句和 Manage_where 片段结合起来看:

  1. 你调用 Mapper 方法

    java
    // 假设有一个 Manage 对象,你只设置了 id
    Manage condition = new Manage();
    condition.setId(5);
    // 调用删除方法
    manageMapper.deleteByEntity(condition);
  2. MyBatis 接收参数对象:它接收到一个 Manage 类型的对象作为参数。这个对象就是你的“条件实体”,它的非空属性就代表了删除的筛选条件。

  3. 构建 SQL 语句

    • MyBatis 从 delete from manage where 1=1 开始。

    • 然后它引入(include) Manage_where 片段。

    • 在 Manage_where 片段内部,MyBatis 会检查传入的 manage 对象的每一个属性:

      • test="id != null":检查 condition.getId() 是否不为 null。因为是 5,条件为真,所以追加 AND id = #{id}

      • test="userName != null and userName != ''":检查 condition.getUserName()。我们没设置,它是 null,条件为假,这个 <if> 标签内的 SQL 会被完全忽略

      • 同理,passWord 和 realName 也为空,它们的条件判断也为假,对应的 SQL 也不会生成。

  4. 生成最终 SQL
    最终发送到数据库的 SQL 语句变成了:

    sql
    DELETE FROM manage 
    WHERE 1=1 
    AND id = ?;

    PreparedStatement 的参数 ? 会被设置为 5

  5. 执行删除:数据库执行这条 SQL,删除所有 id = 5 的记录。

为什么需要 WHERE 1=1

这是一个常见的 SQL 技巧,目的是为了避免动态拼接 SQL 时出现语法错误

  • 如果没有 1=1,并且所有 <if> 条件都不满足,SQL 会变成:

    sql
    DELETE FROM manage WHERE

    这显然是一条错误的 SQL,因为 WHERE 后面没有条件。

  • 如果只有第一个条件满足,SQL 会变成:

    sql
    DELETE FROM manage WHERE AND id = ?

    这里的 WHERE AND 也是语法错误。

  • 加上 WHERE 1=1 之后

    • 如果所有条件都不满足:DELETE ... WHERE 1=1 (这是一条合法的SQL,会删除所有记录,使用时需谨慎!)

    • 如果条件满足:DELETE ... WHERE 1=1 AND id = ? (语法完全正确)

1=1 是一个永远为真的条件,它确保了 WHERE 关键字后面总是有内容,从而让后续的 AND ... 能够正确地拼接上去。

总结

所以,并不是实体类本身能删除数据,而是:

  1. 实体类充当了“条件容器”的角色:它的属性值决定了删除操作的条件。

  2. 动态 SQL (<if> 标签) 是真正的“魔法”:它根据实体对象中哪些属性有值,来动态地、有选择地生成 WHERE 子句的条件。

  3. WHERE 1=1 是语法糖:它保证了动态拼接过程的灵活性,避免了语法错误。

这种设计非常灵活和强大。你可以通过设置实体对象的不同属性组合,来实现多种不同的删除条件,而无需编写多个独立的删除方法。例如:

  • 只设置 id -> 根据主键删除。

  • 只设置 userName -> 删除所有该用户名的记录。

  • 同时设置 userName 和 realName -> 删除同时匹配用户名和真实名的记录。

警告:使用这种方式要非常小心,如果你传入一个全新的、所有属性都为 null 的实体对象,生成的 SQL 将是 DELETE FROM manage WHERE 1=1,这会清空整个表!在实际项目中,通常会在业务层进行校验,防止误删。

 
 
 
 
 
 
 
 
 
 
 
http://www.wxhsa.cn/company.asp?id=7019

相关文章:

  • 调教分块代码
  • 100 粉粉福
  • My All Math
  • 【Azure环境】使用ARM Template部署Policy模板时候报错不支持filed函数: The template function field is not valid.
  • CDQ分治
  • 开源AI大模型、AI智能名片与S2B2C商城小代码:从“不出现=不存在”到“精准存在”的数字化转型路径
  • 202509 组合数学与计数类 DP 笔记
  • edu 106 E(LCS dp + 多源bfs优化)
  • ABC310E NAND repeatedly 题解
  • MyBatis插入语句配置
  • 操作运算符
  • 看 NOI2025 游记记
  • 整体二分
  • 得力 - Bruce
  • 短视频营销运营导师张伽赫,绳木传媒AI+短视频引领企业数字化变革
  • 详细介绍:还在重启应用改 Topic?Spring Boot 动态 Kafka 消费的“终极形态”
  • 用 TensorFlow 和 CNN 实现验证码识别
  • 用 PyTorch 和 CNN 进行验证码识别
  • 用 Keras 和 CNN 进行验证码识别
  • 从 Bank Conflict 数学表示看 Buffer 设计 Trade-Off
  • 被彼此笼罩 任泪水将我们缠绕 深陷入恶魔的拥抱 在阴冷黑暗处灼烧 吞下这毒药
  • mysql无法连接服务器的mysql #mysql8
  • DAG 最小路径覆盖问题 笔记
  • SP3D c# 开发独立的exe
  • python错误code
  • 瑞 ping 我
  • java八股文笔记 - 指南
  • NOIP 模拟赛十六
  • 【AT_dp_y】Grid 2 - Harvey
  • C#十五天 026多态重写 027抽象类与开闭原则 028接口,依赖反转,单元测试