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
11
URL справочной документации изменен
Mayjak
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);
digitaljoel
источник
Спасибо, это работает. Искал более «чистое» решение, т.е. без написания @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);

}
Dzinot
источник
Это работает для всех интерфейсов, расширяющих интерфейс CrudRepository .
Дзинот
1
Это не будет работать, если размер идентификатора больше 1000 или определенный размер в зависимости от БД. Как насчет этого? List <Inventory> findByIdIn (идентификаторы List <Long>, Pageable pageable);
Джули