Автор оригинала: 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%';
Во-первых, давайте определим методы запроса, используя Содержащие , Содержит, и Содержит :
ListfindByTitleContaining(String title); List findByTitleContains(String title); List findByTitleIsContaining(String title);
Давайте назовем наши методы запроса с частичным названием в :
Listresults = movieRepository.findByTitleContaining("in"); assertEquals(3, results.size()); results = movieRepository.findByTitleIsContaining("in"); assertEquals(3, results.size()); results = movieRepository.findByTitleContains("in"); assertEquals(3, results.size());
Мы можем ожидать, что каждый из трех методов даст одинаковые результаты.
Весна также предоставляет нам Нравится ключевое слово, но оно ведет себя несколько иначе в том смысле, что мы обязаны указывать подстановочный знак в нашем параметре поиска.
Давайте определим ПОДОБНЫЙ метод запроса:
ListfindByTitleLike(String title);
Теперь давайте вызовем наш findByTitleLike метод с тем же значением, которое мы использовали ранее, но с использованием подстановочных знаков:
results = movieRepository.findByTitleLike("%in%"); assertEquals(3, results.size());
3.2. Начинается с
Теперь давайте рассмотрим следующий запрос:
SELECT * FROM Movie WHERE Rating LIKE 'PG%';
Давайте используем ключевое слово StartsWith для создания метода запроса:
ListfindByRatingStartsWith(String rating);
Определив наш метод, давайте назовем его значением PG :
Listresults = movieRepository.findByRatingStartsWith("PG"); assertEquals(6, results.size());
3.3. Конец с
Spring предоставляет нам противоположную функциональность с помощью конец с ключевое слово.
Давайте рассмотрим этот запрос:
SELECT * FROM Movie WHERE director LIKE '%Burton';
Теперь давайте определим метод EndsWith запроса:
ListfindByDirectorEndsWith(String director);
Как только мы определим наш метод, давайте вызовем его с параметром Burton :
Listresults = movieRepository.findByDirectorEndsWith("Burton"); assertEquals(1, results.size());
3.4. Нечувствительность к регистру
Мы часто хотим найти все записи, содержащие определенную строку, независимо от регистра. В SQL мы могли бы сделать это, заставив столбец содержать все заглавные или строчные буквы и указав те же значения, которые мы запрашиваем.
С помощью Spring JPA мы можем использовать Игнорирование ключевое слово в сочетании с одним из наших других ключевых слов:
ListfindByTitleContainingIgnoreCase(String title);
Теперь мы можем вызвать метод с помощью и ожидать получения результатов, содержащих как строчные, так и прописные буквы:
Listresults = movieRepository.findByTitleContainingIgnoreCase("the"); assertEquals(2, results.size());
3.5. Не
Иногда мы хотим найти все записи, которые не содержат определенной строки. Для этого мы можем использовать ключевые слова Не содержит , Не Содержит и Не нравится .
Давайте определим запрос, используя Не содержащий , чтобы найти фильмы с рейтингами, которые не содержат PG :
ListfindByRatingNotContaining(String rating);
Теперь давайте вызовем наш недавно определенный метод:
Listresults = movieRepository.findByRatingNotContaining("PG"); assertEquals(1, results.size());
Чтобы обеспечить функциональность, позволяющую находить записи, в которых директор не начинается с определенной строки, давайте использовать ключевое слово NotLike , чтобы сохранить контроль над размещением наших подстановочных знаков:
ListfindByDirectorNotLike(String director);
Наконец, давайте вызовем метод, чтобы найти все фильмы, где имя режиссера начинается с чего-то другого, чем An :
Listresults = movieRepository.findByDirectorNotLike("An%"); assertEquals(5, results.size());
Мы можем использовать Не нравится аналогичным образом для выполнения Не в сочетании с Заканчивается своего рода функциональностью.
4. Использование @Query
Иногда нам нужно создавать запросы, которые слишком сложны для методов запроса или приведут к абсурдно длинным именам методов. В этих случаях мы можем использовать аннотацию @Query для запроса нашей базы данных.
4.1. Именованные Параметры
Для целей сравнения давайте создадим запрос, эквивалентный findByTitle, содержащему метод, который мы определили ранее:
@Query("SELECT m FROM Movie m WHERE m.title LIKE %:title%") ListsearchByTitleLike(@Param("title") String title);
Мы включаем наши подстановочные знаки в запрос, который мы предоставляем. Аннотация @Param важна здесь, потому что мы используем именованный параметр.
4.2. Упорядоченные Параметры
В дополнение к именованным параметрам мы можем использовать упорядоченные параметры в наших запросах:
@Query("SELECT m FROM Movie m WHERE m.rating LIKE ?1%") ListsearchByRatingStartsWith(String rating);
У нас есть контроль над нашими подстановочными знаками, поэтому этот запрос эквивалентен методу найти по рейтингу, начинающемуся с запроса.
Давайте найдем все фильмы с рейтингом, начинающимся с PG :
Listresults = 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()}") ListsearchByDirectorEndsWith(String director);
Теперь давайте вызовем наш метод со значением Бертон :
Listresults = movieRepository.searchByDirectorEndsWith("Burton"); assertEquals(1, results.size());
5. Заключение
В этом коротком уроке мы узнали, как создавать подобные запросы в репозиториях Spring JPA.
Во-первых, мы узнали, как использовать предоставленные ключевые слова для создания методов запроса. Затем мы узнали, как выполнять те же задачи с помощью параметра @Query как с именованными, так и с упорядоченными параметрами.
Полный пример кода доступен на GitHub .