wake-up-neo.com

JPA-Abfrage für Federdaten mit Parametereigenschaften

Was ist die einfachste Methode zum Deklarieren einer JPA-Abfrage für Spring-Daten, bei der die Eigenschaften eines Eingabeparameters als Abfrageparameter verwendet werden?

Angenommen, ich habe eine Entitätsklasse:

public class Person {
    @Id
    private long id;

    @Column
    private String forename;

    @Column
    private String surname;
}

und eine andere Klasse:

public class Name {
    private String forename;
    private String surname;

    [constructor and getters]
}

... dann möchte ich ein Spring-Daten-Repository wie folgt schreiben:

public interface PersonRepository extends CrudRepository<Person, Long> {
    @Query("select p from Person p where p.forename = ?1.forename and p.surname = ?1.surname")
    findByName(Name name);
}

... aber Spring data/JPA mag es nicht, wenn ich Eigenschaftsnamen im Parameter ?1 spezifiziere.

Was ist die schönste Alternative?

46
Kkkev

Dieser Link hilft Ihnen: Spring Data JPA M1 mit unterstützten SpEL-Ausdrücken. Das ähnliche Beispiel wäre:

@Query("select u from User u where u.firstname = :#{#customer.firstname}")
List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);

https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions

92
sunday

Definieren Sie die Abfragemethode mit Signaturen wie folgt.

@Query(select p from Person p where p.forename = :forename and p.surname = :surname)
User findByForenameAndSurname(@Param("surname") String lastname,
                             @Param("forename") String firstname);
}

Weitere Einzelheiten finden Sie in der JPA-Referenz für Federdaten

20
CuriosMind...

Was Sie wollen, ist nicht möglich. Sie müssen zwei Parameter erstellen und diese separat binden:

select p from Person p where p.forename = :forename and p.surname = :surname
...
query.setParameter("forename", name.getForename());
query.setParameter("surname", name.getSurname());
10
JB Nizet

Sie können so etwas ausprobieren:

public interface PersonRepository extends CrudRepository<Person, Long> {
       @Query("select p from Person AS p"
       + " ,Name AS n"  
       + " where p.forename = n.forename "
       + " and p.surname = n.surname"
       + " and n = :name")
       Set<Person>findByName(@Param("name") Name name);
    }
6
Casi

Sie können es auch mit einer Standardmethode für die Benutzeroberfläche lösen:

 @Query(select p from Person p where p.forename = :forename and p.surname = :surname)
User findByForenameAndSurname(@Param("surname") String lastname,
                         @Param("forename") String firstname);

default User findByName(Name name) {
  return findByForenameAndSurname(name.getLastname(), name.getFirstname());
}

Natürlich hätten Sie die aktuelle Repository-Funktion immer noch öffentlich sichtbar ...

4
mmey

wenn wir JpaRepository verwenden, werden die Abfragen intern erstellt.

Probe

findByLastnameAndFirstname (String lastname, String firstname)

findByLastnameOrFirstname (String lastname, String firstname)

findByStartDateBetween (Datum Datum1, Datum2)

findById (int id)

Anmerkung

wenn wir komplexe Abfragen benötigen, müssen wir manuelle Abfragen wie schreiben

@Query("SELECT salesOrder FROM SalesOrder salesOrder WHERE salesOrder.clientId=:clientId AND salesOrder.driver_username=:driver_username AND salesOrder.date>=:fdate AND salesOrder.date<=:tdate ")
 @Transactional(readOnly=true)
 List<SalesOrder> findAllSalesByDriver(@Param("clientId")Integer clientId, @Param("driver_username")String driver_username, @Param("fdate") Date fDate, @Param("tdate") Date tdate);
1
Mohammad

Arbeitest du mit einem @Service auch? Denn wenn Sie sind, dann können Sie @Autowired Ihr PersonRepository zum @Service und rufen Sie dann im Service einfach die Klasse Name auf und verwenden Sie das von @CuriosMind ... vorgeschlagene Formular:

@Query(select p from Person p where p.forename = :forename and p.surname = :surname)
User findByForenameAndSurname(@Param("surname") String lastname,
                         @Param("forename") String firstname);
}

wenn Sie die Methode aus dem Repository im Service aufrufen, können Sie diese Parameter übergeben.

1
Leo