如何使用 JPQL 创建动态更新查询?

Posted

技术标签:

【中文标题】如何使用 JPQL 创建动态更新查询?【英文标题】:How to create a dyncamic update query with JPQL? 【发布时间】:2021-08-10 12:33:33 【问题描述】:

我必须通过确保它已经存在于数据库中来更新一个实体(主键不是自动生成的)。因此我不能只使用save() 方法来解决这个问题。必须有一种方法来确保插入的主键已经存在。要克服这个问题,我知道我可以采用以下几种方法。但我发现创建自己的更新语句是解决此问题的最佳方法。

所以我需要使用 JPQL 创建一个动态更新查询。我知道您会说为什么不使用getOne()findOne() 之类的方法并为实体和save() 设置必要的字段。但我认为使用findOne()getOne() 会导致额外的db hit 来获取相关实体。所以我可以通过自定义更新查询来省略获取。

我想使用@DynamicUpdate 也无法解决问题,因为据我所知,它还会从数据库中获取实体以在更新期间比较更改的字段。

因此,上述两种方法都会导致额外的数据库命中。

那么有没有办法编写一个自定义 jpql 查询来只更新不为空的字段。

我通过编写动态 where 子句实现了类似的获取行为。但没有找到对更新执行相同操作的方法。

例如使用 JPQL 进行动态选择:

SELECT  d FROM TAndC d WHERE (:termStatus is null or d.termStatus= :termStatus ) AND (:termType is null or d.termType=:termType) AND (:termVersion is null or d.termVersion=:termVersion)"

【问题讨论】:

【参考方案1】:
@Modifying
@Query("update entity e set e.obj1=:obj1 and e.obj2=:obj2 where e.id=:id")
public void updateCustom(String obj1, String obj2, String id);

我写了一个伪代码。 使用弹簧数据是可能的。

您还可以使用 jpa 实体管理器以编程方式创建更新语句和动态查询

【讨论】:

我需要做的是在更新语句中有一组动态字段,就像在我的 where 条件中一样。所以我只能更新作为方法参数传递的非 null 字段。请参考我发布的select语句。你可以看到我的where close后面是一组可以为null的属性。所以select语句将在not null属性下搜索结果。

以上是关于如何使用 JPQL 创建动态更新查询?的主要内容,如果未能解决你的问题,请参考以下文章

JPQL / Hibernate 查询的动态表名

在 MS Access 中,创建动态查询后,如何使用记录集中的相应值更新表单上的文本框?

JPQL 更新查询如何处理@Version 字段?

JPQL 动态查询接受多天

我如何执行查询集选择字段的动态更新?

JPQL 到 SQL 使用 Hibernate 更新查询交叉连接问题