Рубрики
Без рубрики

НАПРИМЕР, запросы в репозиториях Spring JPA

Узнайте, как создавать подобные запросы в репозиториях Spring JPA.

Автор оригинала: Amy DeGregorio.

1. введение

В этом кратком руководстве мы рассмотрим различные способы создания подобных запросов в репозиториях Spring JPA .

Мы начнем с рассмотрения различных ключевых слов, которые мы можем использовать при создании методов запроса. Затем мы рассмотрим аннотацию @Query с именованными и упорядоченными параметрами.

2. Настройка

В нашем примере мы будем запрашивать таблицу фильм .

Давайте определим нашу Кино сущность:

@Entity
public class Movie {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    private String title;
    private String director;
    private String rating;
    private int duration;

    // standard getters and setters
}

Определив нашу сущность Movie , давайте создадим несколько примеров операторов вставки:

INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(1, 'Godzilla: King of the Monsters', ' Michael Dougherty', 'PG-13', 132);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(2, 'Avengers: Endgame', 'Anthony Russo', 'PG-13', 181);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(3, 'Captain Marvel', 'Anna Boden', 'PG-13', 123);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(4, 'Dumbo', 'Tim Burton', 'PG', 112);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(5, 'Booksmart', 'Olivia Wilde', 'R', 102);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(6, 'Aladdin', 'Guy Ritchie', 'PG', 128);
INSERT INTO movie(id, title, director, rating, duration) 
    VALUES(7, 'The Sun Is Also a Star', 'Ry Russo-Young', 'PG-13', 100);

3. КАК Методы запроса

Для многих простых сценариев, подобных сценариям запросов, мы можем использовать различные ключевые слова для создания методов запросов в наших репозиториях.

Давайте рассмотрим их сейчас.

3.1. Содержит, Содержит, содержит и тому Подобное

Давайте посмотрим, как мы можем выполнить следующий ПОДОБНЫЙ запрос с помощью метода запроса:

SELECT * FROM movie WHERE title LIKE '%in%';

Во-первых, давайте определим методы запроса, используя Содержащие , Содержит, и Содержит :

List findByTitleContaining(String title);
List findByTitleContains(String title);
List findByTitleIsContaining(String title);

Давайте назовем наши методы запроса с частичным названием в :

List results = movieRepository.findByTitleContaining("in");
assertEquals(3, results.size());

results = movieRepository.findByTitleIsContaining("in");
assertEquals(3, results.size());

results = movieRepository.findByTitleContains("in");
assertEquals(3, results.size());

Мы можем ожидать, что каждый из трех методов даст одинаковые результаты.

Весна также предоставляет нам Нравится ключевое слово, но оно ведет себя несколько иначе в том смысле, что мы обязаны указывать подстановочный знак в нашем параметре поиска.

Давайте определим ПОДОБНЫЙ метод запроса:

List findByTitleLike(String title);

Теперь давайте вызовем наш findByTitleLike метод с тем же значением, которое мы использовали ранее, но с использованием подстановочных знаков:

results = movieRepository.findByTitleLike("%in%");
assertEquals(3, results.size());

3.2. Начинается с

Теперь давайте рассмотрим следующий запрос:

SELECT * FROM Movie WHERE Rating LIKE 'PG%';

Давайте используем ключевое слово StartsWith для создания метода запроса:

List findByRatingStartsWith(String rating);

Определив наш метод, давайте назовем его значением PG :

List results = movieRepository.findByRatingStartsWith("PG");
assertEquals(6, results.size());

3.3. Конец с

Spring предоставляет нам противоположную функциональность с помощью конец с ключевое слово.

Давайте рассмотрим этот запрос:

SELECT * FROM Movie WHERE director LIKE '%Burton';

Теперь давайте определим метод EndsWith запроса:

List findByDirectorEndsWith(String director);

Как только мы определим наш метод, давайте вызовем его с параметром Burton :

List results = movieRepository.findByDirectorEndsWith("Burton");
assertEquals(1, results.size());

3.4. Нечувствительность к регистру

Мы часто хотим найти все записи, содержащие определенную строку, независимо от регистра. В SQL мы могли бы сделать это, заставив столбец содержать все заглавные или строчные буквы и указав те же значения, которые мы запрашиваем.

С помощью Spring JPA мы можем использовать Игнорирование ключевое слово в сочетании с одним из наших других ключевых слов:

List findByTitleContainingIgnoreCase(String title);

Теперь мы можем вызвать метод с помощью и ожидать получения результатов, содержащих как строчные, так и прописные буквы:

List results = movieRepository.findByTitleContainingIgnoreCase("the");
assertEquals(2, results.size());

3.5. Не

Иногда мы хотим найти все записи, которые не содержат определенной строки. Для этого мы можем использовать ключевые слова Не содержит , Не Содержит и Не нравится .

Давайте определим запрос, используя Не содержащий , чтобы найти фильмы с рейтингами, которые не содержат PG :

List findByRatingNotContaining(String rating);

Теперь давайте вызовем наш недавно определенный метод:

List results = movieRepository.findByRatingNotContaining("PG");
assertEquals(1, results.size());

Чтобы обеспечить функциональность, позволяющую находить записи, в которых директор не начинается с определенной строки, давайте использовать ключевое слово NotLike , чтобы сохранить контроль над размещением наших подстановочных знаков:

List findByDirectorNotLike(String director);

Наконец, давайте вызовем метод, чтобы найти все фильмы, где имя режиссера начинается с чего-то другого, чем An :

List results = movieRepository.findByDirectorNotLike("An%");
assertEquals(5, results.size());

Мы можем использовать Не нравится аналогичным образом для выполнения Не в сочетании с Заканчивается своего рода функциональностью.

4. Использование @Query

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

4.1. Именованные Параметры

Для целей сравнения давайте создадим запрос, эквивалентный findByTitle, содержащему метод, который мы определили ранее:

@Query("SELECT m FROM Movie m WHERE m.title LIKE %:title%")
List searchByTitleLike(@Param("title") String title);

Мы включаем наши подстановочные знаки в запрос, который мы предоставляем. Аннотация @Param важна здесь, потому что мы используем именованный параметр.

4.2. Упорядоченные Параметры

В дополнение к именованным параметрам мы можем использовать упорядоченные параметры в наших запросах:

@Query("SELECT m FROM Movie m WHERE m.rating LIKE ?1%")
List searchByRatingStartsWith(String rating);

У нас есть контроль над нашими подстановочными знаками, поэтому этот запрос эквивалентен методу найти по рейтингу, начинающемуся с запроса.

Давайте найдем все фильмы с рейтингом, начинающимся с PG :

List results = movieRepository.searchByRatingStartsWith("PG");
assertEquals(6, results.size());

Когда мы используем упорядоченные параметры в подобных запросах с ненадежными данными, мы должны избегать входящих значений поиска.

Если мы используем Spring Boot 2.4.1 или более позднюю версию, мы можем использовать метод SpEL |/escape :

@Query("SELECT m FROM Movie m WHERE m.director LIKE %?#{escape([0])} escape ?#{escapeCharacter()}")
List searchByDirectorEndsWith(String director);

Теперь давайте вызовем наш метод со значением Бертон :

List results = movieRepository.searchByDirectorEndsWith("Burton");
assertEquals(1, results.size());

5. Заключение

В этом коротком уроке мы узнали, как создавать подобные запросы в репозиториях Spring JPA.

Во-первых, мы узнали, как использовать предоставленные ключевые слова для создания методов запроса. Затем мы узнали, как выполнять те же задачи с помощью параметра @Query как с именованными, так и с упорядоченными параметрами.

Полный пример кода доступен на GitHub .