Spring CrudRepository findByInventoryIds(List <Long> inventoryIdList) - 相当于IN子句

Esp*_*sso 150 java spring jpa spring-data spring-data-jpa

在Spring CrudRepository中,我们是否支持字段的"IN子句"?即类似于以下内容?

 findByInventoryIds(List<Long> inventoryIdList) 
Run Code Online (Sandbox Code Playgroud)

如果没有这样的支持,可以考虑哪些优雅的选择?针对每个id的触发查询可能不是最佳的.

Oli*_*ohm 253

findByInventoryIdIn(List<Long> inventoryIdList) 应该做的伎俩.

HTTP请求参数格式如下:

Yes ?id=1,2,3
No  ?id=1&id=2&id=3
Run Code Online (Sandbox Code Playgroud)

可以在当前文档列表中找到JPA存储库关键字的完整列表.它表明它IsIn是等价的 - 如果你更喜欢动词的可读性 - 而且JPA也支持NotInIsNotIn.

  • [参考文档](http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords)URL改变 (11认同)
  • 我很好奇问题(甚至答案)的作者是否检查了接受的解决方案产生的查询数量。来自问题:“为每个 id 触发查询可能不是最佳的。”。接受的代码将对每个实体进行查询。因此,如果 inventoryIdList.size == 100,此代码将使用可能的连接和其他内容进行 100 次选择。 (2认同)

dig*_*oel 92

对于Spring CrudRepository中的任何方法,您应该能够自己指定@Query.这样的事情应该有效:

@Query( "select o from MyObject o where inventoryId in :ids" )
List<MyObject> findByInventoryIds(@Param("ids") List<Long> inventoryIdList);
Run Code Online (Sandbox Code Playgroud)

  • Oliver Gierke是能够知道答案的人,他拥有"更清洁"的解决方案.你应该接受他的回答. (2认同)
  • 伟大的!我使用了一个`Set&lt;String&gt;` 作为参数,效果很好。 (2认同)

小智 16

是的,这是支持的.

查看此处提供的文档,了解方法名称中支持的关键字.

您可以在存储库界面中定义方法,而无需使用@Query注释并编写自定义查询.在你的情况下,它将如下:

List<Inventory> findByIdIn(List<Long> ids);
Run Code Online (Sandbox Code Playgroud)

我假设您有Inventory实体和InventoryRepository接口.您的案例中的代码应如下所示:

实体

@Entity
public class Inventory implements Serializable {

  private static final long serialVersionUID = 1L;

  private Long id;

  // other fields
  // getters/setters

}
Run Code Online (Sandbox Code Playgroud)

存储库

@Repository
@Transactional
public interface InventoryRepository extends PagingAndSortingRepository<Inventory, Long> {

  List<Inventory> findByIdIn(List<Long> ids);

}
Run Code Online (Sandbox Code Playgroud)

  • 如果 ids 大小超过 1000 或特定大小,这将不起作用,具体取决于数据库。这个怎么样?**List&lt;Inventory&gt; findByIdIn(List&lt;Long&gt; ids, Pageable pageable);** (2认同)