LIKE Pertanyaan di Repositori JPA Spring

1. Pengenalan

Dalam tutorial ringkas ini, kita akan membahas pelbagai cara membuat pertanyaan LIKE di Spring JPA Repositories.

Kita akan mulakan dengan melihat pelbagai kata kunci yang boleh kita gunakan semasa membuat kaedah pertanyaan. Kemudian, kami akan merangkumi anotasi @Query dengan parameter bernama dan tertib .

2. Persediaan

Sebagai contoh, kami akan membuat pertanyaan mengenai jadual filem .

Mari tentukan entiti Filem kami :

@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 }

Dengan entiti Filem kami yang ditentukan, mari buat beberapa contoh penyataan sisipan:

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 Kaedah Pertanyaan

Untuk banyak senario pertanyaan LIKE yang mudah, kami dapat memanfaatkan pelbagai kata kunci untuk membuat kaedah pertanyaan di repositori kami.

Mari kita menerokainya sekarang.

3.1. Mengandungi , Mengandungi , IsContaining dan Suka

Mari lihat bagaimana kita dapat melakukan pertanyaan LIKE berikut dengan kaedah pertanyaan:

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

Pertama, mari tentukan kaedah pertanyaan menggunakan Containing , Contains, dan IsContaining :

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

Mari hubungi kaedah pertanyaan kami dengan tajuk separa dalam :

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

Kita boleh mengharapkan masing-masing dari tiga kaedah menghasilkan hasil yang sama.

Spring juga memberi kami kata kunci Suka , tetapi berkelakuan sedikit berbeza kerana kami diminta untuk memberikan watak wildcard dengan parameter carian kami.

Mari tentukan kaedah pertanyaan LIKE:

List findByTitleLike(String title);

Sekarang, mari kita sebut kaedah findByTitleLike kami dengan nilai yang sama seperti yang kami gunakan sebelumnya tetapi termasuk watak wildcard:

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

3.2. Bermula dengan

Sekarang, mari kita lihat pertanyaan berikut:

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

Mari gunakan kata kunci StartsWith untuk membuat kaedah pertanyaan:

List findByRatingStartsWith(String rating);

Dengan kaedah yang ditentukan, mari kita sebut dengan nilai PG :

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

3.3. TamatDengan

Spring memberi kita fungsi sebaliknya dengan kata kunci EndsWith .

Mari pertimbangkan pertanyaan ini:

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

Sekarang, mari tentukan kaedah pertanyaan EndsWith :

List findByDirectorEndsWith(String director);

Setelah kami menentukan kaedah kami, mari kita sebut dengan parameter Burton :

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

3.4. Ketidakpekaan Kes

Kami sering ingin mencari semua rekod yang mengandungi rentetan tertentu tanpa mengira kes. Dalam SQL, kami mungkin dapat melakukannya dengan memaksa lajur ke semua huruf besar atau huruf kecil dan memberikan nilai yang sama dengan yang kami tanyakan.

Dengan Spring JPA, kita dapat menggunakan kata kunci IgnoreCase yang digabungkan dengan salah satu kata kunci kami yang lain:

List findByTitleContainingIgnoreCase(String title);

Sekarang kita boleh memanggil kaedah dengan itu dan mengharapkan untuk mendapatkan hasil yang mengandungi kedua-dua, keputusan berpendapatan rendah dan huruf besar:

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

3.5. Tidak

Kadang-kadang kita ingin mencari semua rekod yang tidak mengandungi rentetan tertentu. Kita boleh menggunakan kata kunci NotContains , NotContaining, dan NotLike untuk melakukannya.

Mari tentukan pertanyaan menggunakan NotContaining untuk mencari filem dengan penilaian yang tidak mengandungi PG :

List findByRatingNotContaining(String rating);

Sekarang, mari kita sebut kaedah yang baru ditentukan:

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

Untuk mencapai fungsi yang menemui rekod di mana pengarah tidak bermula dengan rentetan tertentu, mari gunakan kata kunci NotLike untuk mengekalkan kawalan terhadap penempatan kad liar kami:

List findByDirectorNotLike(String director);

Akhirnya, mari kita panggil kaedah untuk mencari semua filem di mana nama pengarahnya bermula dengan sesuatu selain An :

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

Kita boleh menggunakan NotLike dengan cara yang serupa untuk mencapai Not yang digabungkan dengan fungsi EndsWith .

4. Menggunakan @Query

Kadang-kadang kita perlu membuat pertanyaan yang terlalu rumit untuk Kaedah Pertanyaan atau akan menghasilkan nama kaedah yang panjang. Dalam kes tersebut, kita dapat menggunakan anotasi @Query untuk menanyakan pangkalan data kami.

4.1. Parameter Dinamakan

Untuk tujuan perbandingan, mari buat pertanyaan yang setara dengan kaedah findByTitleContaining yang kami tentukan sebelumnya:

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

Kami memasukkan kad liar kami dalam pertanyaan yang kami berikan. The @param anotasi adalah penting di sini kerana kita menggunakan parameter yang dinamakan.

4.2. Parameter Teratur

Selain parameter yang dinamakan, kami dapat menggunakan parameter yang disusun dalam pertanyaan kami:

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

Kami mempunyai kawalan ke atas wildcard kami, jadi pertanyaan ini setara dengan kaedah pertanyaan findByRatingStartsWith .

Mari cari semua filem dengan penilaian bermula dengan PG :

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

Apabila kita menggunakan parameter yang diperintahkan dalam pertanyaan LIKE dengan data yang tidak dipercaya, kita harus melepaskan nilai carian masuk.

Sekiranya kita menggunakan Spring Boot 2.4.1 atau lebih baru, kita boleh menggunakan kaedah melarikan diri SpEL :

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

Sekarang, mari sebut kaedah kami dengan nilai Burton :

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

5. Kesimpulan

Dalam tutorial ringkas ini, kami belajar bagaimana membuat pertanyaan LIKE di Spring JPA Repositories.

Pertama, kami belajar bagaimana menggunakan kata kunci yang disediakan untuk membuat kaedah pertanyaan. Kemudian, kami belajar bagaimana menyelesaikan tugas yang sama menggunakan parameter @Query dengan kedua-dua parameter bernama dan tertib .

Kod contoh lengkap boleh didapati di GitHub.