【问题标题】:SpringData JPA: Query with collection of entity as parameterSpring Data JPA:使用实体集合作为参数进行查询
【发布时间】:2021-02-24 14:35:59
【问题描述】:

我有一个要对其执行更新的实体列表,我知道我可以使用字符串/整数列表等更新表作为参数,例如

  @Query("update tableName i set i.isUpdated = true where i.id in :ids")
  void markAsUpdated(@Param("ids") List<Integer> itemIds);

我试图避免重复将实体列表转换为 ID 列表以便在数据库中进行查询。我知道有deleteAlldeleteInBatch 命令接受参数作为实体列表。

如何在 JPA Query 中执行此操作,我尝试了以下方法,但还没有成功。

  @Modifying(flushAutomatically = true, clearAutomatically = true)
  @Query("update tableName i set i.updated = true where i in :items")
  void markAsUpdated(@Param("items") List<Item> items)

【问题讨论】:

  • 我认为这是不可能的,如果您查看SimpleJpaRepository.deleteInBatch 的实现,您会发现将实体转换为 id 列表是两害相权取其轻。
  • 另外,如果“重复转换”是指必须在代码周围的多个位置进行转换,请注意,您可以简单地将第二种方法实现为委托给第一种方法的默认方法
  • @crizzis 谢谢,重复转换是指对于具有相似查询的不同实体,我需要重复转换,我不能将不同的实体转换委托给相同的方法,对吗?至少在不使用一些技巧的情况下并非如此。我会坚持使用我认为的 ID。

标签: spring-boot jpa spring-data-jpa spring-data


【解决方案1】:

查询需要id,它不知道如何处理实体。

您有多种选择:

  • 只需将 id 传递给方法,客户端负责提取 id。
  • 传递实体并使用 SpEL 提取 ID
  • 正如 cmets 中所建议的,使用默认方法来提供这两种 API 并从一个 API 委托给另一个。

至于 cmets 中出现的问题:您可以将提取 id 的方法移动到单个方法中,方法是让相关实体实现类似于此的接口:

interface WithId {
    Long getId();
}

或者通过将 lambda 传递给方法,对单个实体进行转换:

List<ID> extractIds(List<E> entities, Function<E, ID> extractor) {
    // ...
}

【讨论】:

    猜你喜欢
    • 2021-03-17
    • 1970-01-01
    • 2022-07-11
    • 2015-03-20
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    相关资源
    最近更新 更多