web-dev-qa-db-fra.com

Paramètre facultatif Spring Data dans la méthode de requête

Je veux écrire quelques méthodes de requête dans la couche de référentiel. Cette méthode doit ignorer les paramètres nuls. Par exemple:

List<Foo> findByBarAndGoo(Bar barParam, @optional Goo gooParam);

Cette méthode doit être renvoyée Foo par cette condition:

bar == barParam && goo == gooParam;

si gooParam n'est pas nul. si gooParam était null, la condition passe à:

bar == barParam;

Y-a-t'il une solution? Est-ce que quelqu'un peut m'aider?

33
mohammad_1m2

Trop tard pour répondre. Pas sûr de la relation entre Bar et Goo. Vérifiez si Exemple peut vous aider.

Ça a marché pour moi. J'ai une situation similaire, l'entité ser possède un ensemble d'attributs et il existe une méthode findAll qui recherche l'utilisateur en fonction d'attributs (qui sont facultatifs).

Exemple,

  Class User{
    String firstName;
    String lastName;
    String id;
  }

  Class UserService{
     // All are optional
     List<User> findBy(String firstName, String lastName, String id){
        User u = new User();
        u.setFirstName(firstName);
        u.setLastName(lastName);
        u.setId(id);

        userRepository.findAll(Example.of(user));
        // userRepository is a JpaRepository class
     }
  }
7
Shaunak Patel

Je ne pense pas que vous pourrez le faire avec l'approche du nom de méthode pour définir la requête. De la documentation ( ( référence ):

Bien que l'obtention d'une requête dérivée du nom de la méthode soit assez pratique, on peut faire face à la situation dans laquelle soit l'analyseur de nom de méthode ne prend pas en charge le mot clé que l'on souhaite utiliser, soit le nom de la méthode devient inutilement laid. Vous pouvez donc utiliser des requêtes nommées JPA via une convention de dénomination (voir Utilisation de JPA NamedQueries pour plus d'informations) ou plutôt annoter votre méthode de requête avec @Query

Je pense que vous avez cette situation ici, donc la réponse ci-dessous utilise l'approche d'annotation @Query, qui est presque aussi pratique que l'approche du nom de méthode ( reference ).

    @Query("select foo from Foo foo where foo.bar = :bar and "
        + "(:goo is null or foo.goo = :goo)")
    public List<Foo> findByBarAndOptionalGoo(
        @Param("bar") Bar bar, 
        @Param("goo") Goo goo);
22
chaserb

En complément de la réponse de @chaserb, j'ajouterais personnellement le paramètre en tant que type facultatif Java8 pour le rendre explicite dans la signature de la méthode la sémantique qui est un filtre facultatif.

@Query("select foo from Foo foo where foo.bar = :bar and "
   + "(:goo is null or foo.goo = :goo)")
public List<Foo> findByBarAndOptionalGoo(
     @Param("bar") Bar bar, 
     @Param("goo") Optional<Goo> goo);
11
Vitor Reis

Vous pouvez coder cela vous-même en quelques lignes:

List<Foo> findByBarAndOptionalGoo(Bar bar, Goo goo) {
   return (goo == null) ? this.findByBar(bar) : this.findByBarAndGoo(bar, goo);
}

Sinon, je ne sais pas si Spring-Data prend cela en charge.

2
user152468