Ответ
Spring Data JPA предоставляет несколько механизмов для поиска, от простых до сложных:
-
Стандартные CRUD-методы:
findById(ID id),findAll(),existsById(ID id). -
Query Methods (методы по соглашению): Создайте метод в интерфейсе репозитория, и Spring сгенерирует запрос JPQL на основе его имени.
public interface UserRepository extends JpaRepository<User, Long> { // Простой поиск по полю List<User> findByLastName(String lastName); // Поиск с условиями List<User> findByAgeGreaterThan(int age); List<User> findByEmailAndActiveTrue(String email); // Сортировка и пагинация Page<User> findByLastName(String lastName, Pageable pageable); } -
Аннотация
@Queryдля кастомных JPQL или SQL запросов:@Query("SELECT u FROM User u WHERE u.email = :email") User findUserByEmail(@Param("email") String email); @Query(value = "SELECT * FROM users WHERE active = 1", nativeQuery = true) List<User> findAllActiveUsersNative(); -
Specification API и JpaSpecificationExecutor: Для построения динамических, типобезопасных запросов на уровне бизнес-логики.
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {} // Использование в сервисе: List<User> users = userRepository.findAll( Specification.where(hasName("John").and(isActive())) );
Рекомендация по выбору: Используйте Query Methods для простых запросов, @Query для сложных или оптимизированных, а Specification API — для динамических фильтров.
Ответ 18+ 🔞
Так, слушай, вот эта твоя Spring Data JPA, она же, блядь, как шведский стол — всего навалом, только выбирай. Но если бездумно хватать, можно и обосраться, честно. Вот смотри, как тут всё устроено, по полочкам.
Во-первых, самое простое, что даже дурак не проебёт. Это стандартные штуки из коробки: найти по айдишнику (findById), достать всех (findAll), проверить, есть ли такая сущность вообще (existsById). Это как хлеб с маслом, базис, хуле.
А вот дальше начинается магия, или, как я это называю, «ленивое колдунство». Query Methods. Ты просто пишешь в интерфейсе репозитория метод с правильным именем, а Spring, сука, сам догадывается, какой тебе JPQL-запрос сгенерить. Просто пиздец!
public interface UserRepository extends JpaRepository<User, Long> {
// Найдём всех по фамилии — логично же?
List<User> findByLastName(String lastName);
// А тут всех, кто старше какого-то возраста. Бабки, блядь!
List<User> findByAgeGreaterThan(int age);
// Имейл конкретный И чтоб активный был. Два условия — не хуй собачий.
List<User> findByEmailAndActiveTrue(String email);
// А это уже с пагинацией, чтоб не грузить всё разом, как говно в унитаз.
Page<User> findByLastName(String lastName, Pageable pageable);
}
Чувствуешь? Ни одной аннотации, нихуя! Просто называешь метод — и он работает. Но если тебе кажется, что это слишком просто и хочется своей, особенной, ебаной логики запроса...
Тогда тебе в помощь @Query. Тут ты уже сам бог и царь. Хочешь JPQL, хочешь нативный SQL — только скажи.
@Query("SELECT u FROM User u WHERE u.email = :email")
User findUserByEmail(@Param("email") String email);
// А это когда JPQL уже не канает и надо рубить с плеча нативным SQL
@Query(value = "SELECT * FROM users WHERE active = 1", nativeQuery = true)
List<User> findAllActiveUsersNative();
Но бывает, блядь, такая ситуация: фильтры приходят с фронта, их дохуя, и они все опциональные. Писать кучу if и склеивать строки запроса — это же пиздец, прости господи. На это есть Specification API.
Подключаешь к репозиторию волшебный интерфейс JpaSpecificationExecutor:
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {}
А потом в сервисе строишь эти спецификации, как из кубиков Лего:
// Где-то там у тебя методы, которые возвращают Specification<User>
List<User> users = userRepository.findAll(
Specification.where(hasName("John").and(isActive())) // Примерно так
);
Это для сложных, динамических фильтров, где на лету надо условия добавлять или убирать. Мощная хуйня, но и сложнее.
Так какую же хуйню выбрать, спросишь ты? А я тебе скажу:
- Query Methods — для всего простого, очевидного. Не еби мозг.
@Query— когда твой запрос слишком хитрожопый для соглашений или тебе надо выжать максимум производительности (особенно сnativeQuery).- Specification API — это когда у тебя на сайте фильтры, как у маркетплейса: «показать только красные, но не китайские, с рейтингом выше 4.5, но чтоб со скидкой». Вот тут оно.
Вот и вся философия. Не усложняй, где не надо, а где надо — используй тяжёлую артиллерию.