JPA JPQL IN 子句:如何在 JPA 中使用 IN 子句?

Posted

技术标签:

【中文标题】JPA JPQL IN 子句:如何在 JPA 中使用 IN 子句?【英文标题】:JPA JPQL IN clause: How to use IN clause in JPA? 【发布时间】:2018-06-08 02:20:49 【问题描述】:
@Query("SELECT al FROM Customer al WHERE al.companyCode = ?1 AND al.fileCode IN ?2")

List findallByGroup(int CompanyCode, String groups);

或者

@Query("SELECT al FROM Customer al WHERE al.companyCode = :CompanyCode AND al.fileCode IN :groups")

List<Customer> findallByGroup(@Param("CompanyCode") int CompanyCode,@Param("groups") List<BigInteger> groups);

@Query("SELECT al FROM Customer al WHERE al.companyCode = :CompanyCode AND al.fileCode IN (:groups)")

List<Customer> findallByGroup(@Param("CompanyCode") int CompanyCode,@Param("groups") List<BigInteger> groups);

【问题讨论】:

【参考方案1】:
findAllByCompanyCodeAndFileCodeIn(int CompanyCode, List<String> groups)

您不需要@Query。 Spring数据可以从方法名理解查询。使用上述方法。

【讨论】:

感谢您的帮助。它完成了。但我改变了类似 "List" Not List 不知何故它对我来说失败了,方法结束它正在创建选择查询,如下select*from tab where name = ('ab', 'bc') 这对于mysql来说是非常错误的。有什么解决方法吗? @pvpkiran 我的列名是@Id @Column(name="product_id") private Long productId;试过@Query("select p FROM table_name p where p.productId IN (:productId)") List findAllByProductIdIn(List productId);这个 List findAllByProductIdIn(List productId);两者都不起作用..你能建议一下吗【参考方案2】:

与 OP 的特定查询没有直接关系,但一般与 JPA IN 子句相关:

与 pvpkiran 的回答相反,如果您正在执行 SELECT 查询以外的任何操作(例如 DELETE、UPDATE),使用@Query 可能会更有效:

@Modifying
@Query("DELETE from Customer al where al.fileCode in :groups")
deleteByFileCodeIn(@Param("groups") List<String> groups)

而不是依赖Spring JPA的查询方法:

deleteByFileCodeIn(List<String> groups) // avoid this

原因:

Spring JPA 查询方法对 IN 子句的默认实现是低效的。在底层,它将 1. 首先选择所有符合 IN 条件的记录,然后 2. 为找到的 每个 记录执行 DELETE 语句。

select customer.id as id,... from customer where customer.file_code in (?,?,?,...)
delete from customer where id=?
delete from customer where id=?
delete from customer where id=?
...

这意味着如果有 1000 条匹配记录,它将生成并执行 1000 条删除语句——而不是通常预期的单个 DELETE...IN 语句。

通过将@Query 用于 IN 子句,您可以覆盖 Spring JPA 的默认实现并指定使用更有效的查询。在我自己的测试中,这使大型 (>3K) 数据集的响应时间提高了 10 倍。

需要注意的是,根据数据库的不同,可在 IN 子句中使用的参数数量可能存在限制。这可以通过partitioning 列表来克服。

【讨论】:

以上是关于JPA JPQL IN 子句:如何在 JPA 中使用 IN 子句?的主要内容,如果未能解决你的问题,请参考以下文章

JPA Criteria builder IN 子句查询

JPA中带有IN子句的位置参数

从子句中的jpa eclipselink子查询

JPQL typedquery 中 IN 子句的解析

Spring JPA Hibernate JPQL 查找在 where 子句中传递的项目的索引

无法在 FROM 子句中使用子查询编写 JPQL 查询 - Spring Data Jpa - Hibernate