【问题标题】:Update query performance with Hibernate使用 Hibernate 更新查询性能
【发布时间】:2026-01-31 03:35:02
【问题描述】:

我们正在研究 2 种不同的方法来更新我们的实体:

  1. “标准”更新 - 从数据库中获取,设置字段,持久化。

  2. 我们对每个实体都有一个查询,如下所示:

    String sqlQuery =  "update Entity set entity.field1 = entity.field1, entity.field2 = entity.field2, entity.field3 = entity.field3, ....  entity.fieldn = entity.fieldn"
    

    我们收到更改的字段(及其新值),并将字符串字段(仅那些必需的)替换为新值。即类似:

    for each field : fields {
          sqlQuery.replace(field.fieldName, getNewValue(field));
    }
    executeQuery(sqlQuery);
    

如果这些选项在性能上存在很大差异,有什么想法吗?第二种选择是否可行?有什么优点/缺点?

请忽略 SQL 注入漏洞,上面的例子只是一个例子,我们确实使用 PreparedStatements 来构建查询。

【问题讨论】:

  • 这里最大的维护(为什么要重新发明*)并且您的解决方案对 SQL 注入攻击是开放的。你永远不应该使用字符串替换/concat 来生成 SQL,总是使用带有占位符的 PreparedStatement。如果您想知道性能差异,请进行测试。一般来说,我不会费心自己写,开发会更难(这让你想知道为什么要使用 ORM 工具?)。

标签: java database spring hibernate jpa


【解决方案1】:

然后构建一个混合解决方案?

首先,创建一个 hasmap。

其次,使用 before hasmap 为 PreparedStament 创建一个新查询(以避免 SQL 注入)

第三,设置所有参数。

O(x)=n,其中 n 是参数的数量。

【讨论】:

    【解决方案2】:
    1. 第一个解决方案更加灵活 您可以依靠 Hibernate dirty checking mechanism 来生成正确的更新。这就是为什么 ORM 工具在写入数据时非常出色的一个很好的原因。

    2. 第二种方法再好不过了,因为它可能会生成不同的更新计划,因此您不能在各种列组合中重复使用 PreparedStatement 语句缓存。您可以use JOOQ instead,而不是使用基于字符串的模板(易受 SQL 注入攻击)。 JOOQ 允许您在 Java 中引用表列,因此您可以以类型安全的方式构建 UPDATE 查询。

    【讨论】: