LIKE Query nei repository JPA di primavera

1. Introduzione

In questo breve tutorial, tratteremo vari modi per creare query LIKE nei repository Spring JPA.

Inizieremo esaminando le varie parole chiave che possiamo utilizzare durante la creazione dei metodi di query. Quindi, copriremo l' annotazione @Query con parametri denominati e ordinati.

2. Configurazione

Per il nostro esempio, interrogheremo un tavolo da film .

Definiamo la nostra entità Film :

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

Con la nostra entità Movie definita, creiamo alcune istruzioni di inserimento di esempio:

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. Metodi di query LIKE

Per molti semplici scenari di query LIKE, possiamo trarre vantaggio da una varietà di parole chiave per creare metodi di query nei nostri repository.

Esploriamoli ora.

3.1. Contenente , Contiene , IsContaining e Like

Diamo un'occhiata a come possiamo eseguire la seguente query LIKE con un metodo di query:

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

Innanzitutto, definiamo i metodi di query usando Containing , Contains e IsContain :

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

Chiamiamo i nostri metodi di query con il titolo parziale in :

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

Possiamo aspettarci che ciascuno dei tre metodi restituisca gli stessi risultati.

Spring ci fornisce anche una parola chiave Like , ma si comporta in modo leggermente diverso in quanto ci viene richiesto di fornire il carattere jolly con il nostro parametro di ricerca.

Definiamo un metodo di query LIKE:

List findByTitleLike(String title);

Ora, chiamiamo il nostro metodo findByTitleLike con lo stesso valore che abbiamo usato prima ma includendo i caratteri jolly:

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

3.2. Inizia con

Ora, esaminiamo la seguente query:

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

Usiamo la parola chiave StartsWith per creare un metodo di query:

List findByRatingStartsWith(String rating);

Con il nostro metodo definito, chiamiamolo con il valore PG :

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

3.3. Finisce con

Spring ci fornisce la funzionalità opposta con la parola chiave EndsWith .

Consideriamo questa query:

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

Ora definiamo un metodo di query EndsWith :

List findByDirectorEndsWith(String director);

Una volta definito il nostro metodo, chiamiamolo con il parametro Burton :

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

3.4. Insensibilità alle maiuscole

Spesso vogliamo trovare tutti i record che contengono una certa stringa indipendentemente dal caso. In SQL, potremmo ottenere ciò forzando la colonna a tutte le lettere maiuscole o minuscole e fornendo lo stesso con i valori che stiamo interrogando.

Con Spring JPA, possiamo utilizzare la parola chiave IgnoreCase combinata con una delle nostre altre parole chiave:

List findByTitleContainingIgnoreCase(String title);

Ora siamo in grado di chiamare il metodo con il e si aspettano di ottenere risultati con entrambi, risultati minuscoli e maiuscoli:

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

3.5. Non

A volte vogliamo trovare tutti i record che non contengono una stringa particolare. Possiamo usare le parole chiave NotContains , NotContain e NotLike per farlo.

Definiamo una query utilizzando NotContain per trovare film con valutazioni che non contengono PG :

List findByRatingNotContaining(String rating);

Ora, chiamiamo il nostro metodo appena definito:

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

Per ottenere la funzionalità che trova i record in cui il director non inizia con una stringa particolare, utilizziamo la parola chiave NotLike per mantenere il controllo sul posizionamento dei caratteri jolly:

List findByDirectorNotLike(String director);

Infine, chiamiamo il metodo per trovare tutti i film in cui il nome del regista inizia con qualcosa di diverso da An :

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

Possiamo usare NotLike in modo simile per ottenere una funzionalità Not combinata con EndsWith .

4. Utilizzo di @Query

A volte è necessario creare query troppo complicate per i metodi di query o che risulterebbero in nomi di metodo assurdamente lunghi. In questi casi, possiamo usare l' annotazione @Query per interrogare il nostro database.

4.1. Parametri denominati

A scopo di confronto, creiamo una query equivalente al metodo findByTitleContain che abbiamo definito in precedenza:

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

Includiamo i nostri caratteri jolly nella query che forniamo. L' annotazione @Param è importante qui perché stiamo usando un parametro denominato.

4.2. Parametri ordinati

Oltre ai parametri denominati, possiamo utilizzare parametri ordinati nelle nostre query:

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

Abbiamo il controllo dei nostri caratteri jolly, quindi questa query è l'equivalente del metodo di query findByRatingStartsWith .

Troviamo tutti i film con una valutazione che inizia con PG :

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

Quando utilizziamo parametri ordinati in query LIKE con dati non attendibili, dovremmo sfuggire ai valori di ricerca in arrivo.

Se stiamo usando Spring Boot 2.4.1 o successivo, possiamo usare il metodo di fuga SpEL :

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

Ora, chiamiamo il nostro metodo con il valore Burton :

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

5. conclusione

In questo breve tutorial, abbiamo imparato come creare query LIKE nei repository JPA Spring.

In primo luogo, abbiamo imparato come utilizzare le parole chiave fornite per creare metodi di query. Quindi, abbiamo imparato come eseguire le stesse attività utilizzando il parametro @Query con entrambi i parametri denominati e ordinati.

Il codice di esempio completo è disponibile su GitHub.