LIKE заявки в пролетните хранилища на JPA

1. Въведение

В този бърз урок ще разгледаме различни начини за създаване на LIKE заявки в Spring JPA Repositories.

Ще започнем, като разгледаме различните ключови думи, които можем да използваме, докато създаваме методи за заявка. След това ще покрием анотацията @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. LIKE Query Methods

За много прости сценарии на LIKE заявки можем да се възползваме от различни ключови думи, за да създадем методи за заявки в нашите хранилища.

Нека ги изследваме сега.

3.1. Съдържа , съдържа , съдържа и харесва

Нека разгледаме как можем да изпълним следната LIKE заявка с метод на заявка:

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

Първо, нека да се определят методите за заявка с помощта на съдържание , Съдържа, и IsContaining :

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());

Можем да очакваме всеки от трите метода да върне едни и същи резултати.

Spring също ни предоставя ключова дума Like , но тя се държи малко по-различно, тъй като от нас се изисква да предоставим заместващия знак с нашия параметър за търсене.

Нека дефинираме LIKE метод на заявка:

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 ни предоставя обратната функционалност с ключовата дума EndsWith .

Нека разгледаме тази заявка:

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 можем да използваме ключовата дума IgnoreCase, комбинирана с една от другите ни ключови думи:

List findByTitleContainingIgnoreCase(String title);

Сега можем да се обадите на метода, с по и очаквате да получите резултати, съдържащи и двете, с ниски или главни резултати:

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

3.5. Не

Понякога искаме да намерим всички записи, които не съдържат определен низ. За това можем да използваме ключовите думи NotContains , NotContaining и NotLike .

Нека дефинираме заявка с помощта на NotContaining, за да намерим филми с рейтинги, които не съдържат 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());

Можем да използваме NotLike по подобен начин, за да постигнем Not, комбиниран с EndsWith вид функционалност.

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

Понякога трябва да създадем заявки, които са твърде сложни за методите за заявки или биха довели до абсурдно дълги имена на методи. В тези случаи можем да използваме анотацията @Query, за да заявим нашата база данни.

4.1. Наименовани параметри

За целите на сравнението, нека създадем заявка, еквивалентна на метода findByTitleContaining , който дефинирахме по-рано:

@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);

Ние имаме контрол върху нашите заместващи символи, така че тази заявка е еквивалент на метода за търсене findByRatingStartsWith .

Нека намерим всички филми с рейтинг, започващ с PG :

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

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

Ако използваме 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);

Сега, нека извикаме нашия метод със стойността Burton :

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

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

В този кратък урок научихме как да създаваме LIKE заявки в Spring JPA Repositories.

Първо научихме как да използваме предоставените ключови думи за създаване на методи за заявки. След това научихме как да изпълняваме едни и същи задачи, като използваме параметъра @Query както с имена, така и с подредени параметри.

Пълният примерен код е достъпен в GitHub.