LIKE Requêtes dans les référentiels Spring JPA

1. Introduction

Dans ce tutoriel rapide, nous allons couvrir différentes manières de créer des requêtes LIKE dans les référentiels Spring JPA.

Nous allons commencer par examiner les différents mots-clés que nous pouvons utiliser lors de la création de méthodes de requête. Ensuite, nous couvrirons l' annotation @Query avec des paramètres nommés et ordonnés.

2. Configuration

Pour notre exemple, nous allons interroger une table de film .

Définissons notre entité Movie :

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

Avec notre entité Movie définie, créons quelques exemples d'instructions d'insertion:

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. Méthodes de requête LIKE

Pour de nombreux scénarios de requête LIKE simples, nous pouvons tirer parti d'une variété de mots-clés pour créer des méthodes de requête dans nos référentiels.

Explorons-les maintenant.

3.1. Contenant , Contient , IsContenant et J'aime

Voyons comment nous pouvons effectuer la requête LIKE suivante avec une méthode de requête:

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

Tout d'abord, définissons les méthodes de requête à l'aide de Containing , Contains et IsContaining :

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

Appelons nos méthodes de requête avec le titre partiel en :

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

Nous pouvons nous attendre à ce que chacune des trois méthodes renvoie les mêmes résultats.

Spring nous fournit également un mot-clé Like , mais il se comporte légèrement différemment en ce sens que nous devons fournir le caractère générique avec notre paramètre de recherche.

Définissons une méthode de requête LIKE:

List findByTitleLike(String title);

Maintenant, appelons notre méthode findByTitleLike avec la même valeur que nous avons utilisée auparavant mais en incluant les caractères génériques:

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

3.2. Commence avec

Maintenant, regardons la requête suivante:

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

Utilisons le mot clé StartsWith pour créer une méthode de requête:

List findByRatingStartsWith(String rating);

Avec notre méthode définie, appelons-la avec la valeur PG :

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

3.3. Se termine par

Spring nous fournit la fonctionnalité opposée avec le mot clé EndsWith .

Considérons cette requête:

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

Maintenant, définissons une méthode de requête EndsWith :

List findByDirectorEndsWith(String director);

Une fois que nous avons défini notre méthode, appelons-la avec le paramètre Burton :

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

3.4. Insensibilité à la casse

Nous voulons souvent trouver tous les enregistrements contenant une certaine chaîne quel que soit le cas. En SQL, nous pouvons accomplir cela en forçant la colonne à toutes les lettres majuscules ou minuscules et en fournissant la même chose avec les valeurs que nous recherchons.

Avec Spring JPA, nous pouvons utiliser le mot clé IgnoreCase combiné avec l'un de nos autres mots clés:

List findByTitleContainingIgnoreCase(String title);

Nous pouvons maintenant appeler la méthode avec le et espérer obtenir des résultats contenant à la fois des résultats en minuscules et en majuscules:

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

3.5. ne pas

Parfois, nous voulons trouver tous les enregistrements qui ne contiennent pas de chaîne particulière. Nous pouvons utiliser les mots clés NotContains , NotContaining et NotLike pour ce faire.

Définissons une requête à l'aide de NotContaining pour trouver des films dont les notes ne contiennent pas de PG :

List findByRatingNotContaining(String rating);

Maintenant, appelons notre méthode nouvellement définie:

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

Pour obtenir une fonctionnalité qui trouve des enregistrements où le directeur ne commence pas par une chaîne particulière, utilisons le mot clé NotLike pour garder le contrôle sur notre placement de caractères génériques :

List findByDirectorNotLike(String director);

Enfin, appelons la méthode pour trouver tous les films où le nom du réalisateur commence par autre chose que An :

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

Nous pouvons utiliser NotLike de la même manière pour accomplir une fonctionnalité non combinée avec le type de fonctionnalité EndsWith .

4. Utilisation de @Query

Parfois, nous devons créer des requêtes trop compliquées pour les méthodes de requête ou qui aboutiraient à des noms de méthode absurdement longs. Dans ces cas, nous pouvons utiliser l' annotation @Query pour interroger notre base de données.

4.1. Paramètres nommés

À des fins de comparaison, créons une requête équivalente à la méthode findByTitleContaining que nous avons définie précédemment:

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

Nous incluons nos jokers dans la requête que nous fournissons. L' annotation @Param est importante ici car nous utilisons un paramètre nommé.

4.2. Paramètres ordonnés

En plus des paramètres nommés, nous pouvons utiliser des paramètres ordonnés dans nos requêtes:

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

Nous avons le contrôle de nos caractères génériques, donc cette requête est l'équivalent de la méthode de requête findByRatingStartsWith .

Trouvons tous les films avec une note commençant par PG :

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

Lorsque nous utilisons des paramètres ordonnés dans des requêtes LIKE avec des données non fiables, nous devons échapper aux valeurs de recherche entrantes.

Si nous utilisons Spring Boot 2.4.1 ou version ultérieure, nous pouvons utiliser la méthode d' échappement SpEL :

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

Maintenant, appelons notre méthode avec la valeur Burton :

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

5. Conclusion

Dans ce court didacticiel, nous avons appris à créer des requêtes LIKE dans les référentiels Spring JPA.

Tout d'abord, nous avons appris à utiliser les mots-clés fournis pour créer des méthodes de requête. Ensuite, nous avons appris à accomplir les mêmes tâches à l'aide du paramètre @Query avec des paramètres nommés et ordonnés.

L'exemple de code complet est disponible à l'adresse over sur GitHub.