Spring CrudRepository findByInventoryIds (List <Long> inventoryIdList) - эквивалентно предложению IN


170

В Spring CrudRepository есть ли у нас поддержка «предложения IN» для поля? то есть что-то похожее на следующее?

 findByInventoryIds(List<Long> inventoryIdList) 

Если такая поддержка недоступна, какие элегантные варианты можно рассмотреть? Запросы на запуск для каждого идентификатора могут быть неоптимальными.

Ответы:


284

findByInventoryIdIn(List<Long> inventoryIdList) должен сделать свое дело.

Формат параметра HTTP-запроса будет выглядеть так:

Yes ?id=1,2,3
No  ?id=1&id=2&id=3

Полный список ключевых слов репозитория JPA можно найти в текущем списке документации . Это показывает, что IsInэто эквивалентно - если вы предпочитаете глагол для удобочитаемости - и что JPA также поддерживает NotInи IsNotIn.


Спасибо, это именно то, что я искал. Есть ли у них это задокументировано на странице CrudRepository, или узнать, прочитав код?
— Эспрессо

1
Это на самом деле указано в справочной документации .
— Оливер Дротбом

Спасибо. Этот "драгоценный камень спрятан в приложении B", это правильно :)
— Espresso


1
Для подписи метода: List <Person> findByIdIn (List <Integer> ids); Я получаю сообщение об ошибке: Причина: java.lang.NumberFormatException: Для входной строки: "(1, 2)"
— user64141

103

Для любого метода в Spring CrudRepository у вас должна быть возможность указать @Query самостоятельно. Примерно так должно работать:

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

Спасибо, это работает. Искал более «чистое» решение, т.е. без написания @Query.
— Эспрессо

3
Оливер Герке - человек, который знает ответ на этот вопрос, и у него есть «более чистое» решение. Вы должны принять его ответ.
— digitaljoel 25.09.13

1
Большой! Я использовал Set<String>в качестве параметра, работал хорошо.
— BlueBird

Что, если я хочу передать в мой метод 2 параметра - один список, а другой - обычную строку, это сработает? если да, то как мне назвать мой метод
— user3614936

22

Да, это поддерживается.

Проверьте предоставленную здесь документацию на предмет поддерживаемых ключевых слов внутри имен методов.

Вы можете просто определить метод в интерфейсе репозитория, не используя аннотацию @Query и не создавая собственный запрос. В вашем случае это будет выглядеть следующим образом:

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

Я предполагаю , что у вас есть Инвентарный объект и InventoryRepository интерфейс. Код в вашем случае должен выглядеть так:

Организация

@Entity
public class Inventory implements Serializable {

  private static final long serialVersionUID = 1L;

  private Long id;

  // other fields
  // getters/setters

}

Репозиторий

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

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

}

Это работает для всех интерфейсов, расширяющих интерфейс CrudRepository .
— Дзинот

1
Это не будет работать, если размер идентификатора больше 1000 или определенный размер в зависимости от БД. Как насчет этого? List <Inventory> findByIdIn (идентификаторы List <Long>, Pageable pageable);
— Джули
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.