Abgeleitete Abfragemethoden in Spring Data JPA-Repositorys

1. Einleitung

Bei einfachen Abfragen können Sie leicht ableiten, wie die Abfrage aussehen soll, indem Sie sich den entsprechenden Methodennamen in unserem Code ansehen.

In diesem Tutorial werden wir untersuchen, wie Spring Data JPA diese Idee in Form einer Methodennamenskonvention nutzt.

2. Struktur abgeleiteter Abfragemethoden im Frühjahr

Abgeleitete Methodennamen bestehen aus zwei Hauptteilen, die durch das erste By- Schlüsselwort getrennt sind:

List findByName(String name)

Der erste Teil - wie find - ist der Einführer und der Rest - wie ByName - ist das Kriterium.

Spring Data JPA unterstützt das Suchen, Lesen, Abfragen, Zählen und Abrufen . So hätten wir beispielsweise queryByName durchführen können und Spring Data würde sich gleich verhalten.

Wir können auch Distinct, First oder Top verwenden , um Duplikate zu entfernen oder unsere Ergebnismenge einzuschränken:

List findTop3ByAge()

Der Kriterienteil enthält die entitätsspezifischen Bedingungsausdrücke der Abfrage. Wir können die Bedingungsschlüsselwörter zusammen mit den Eigenschaftsnamen der Entität verwenden. Wir können die Ausdrücke auch mit And und Or verketten, was wir in einem Moment sehen können.

3. Beispielanwendung

Zunächst benötigen wir natürlich eine Anwendung mit Spring Data JPA.

Definieren wir in dieser Anwendung eine Entitätsklasse:

@Table(name = "users") @Entity class User { @Id @GeneratedValue private Integer id; private String name; private Integer age; private ZonedDateTime birthDate; private Boolean active; // standard getters and setters }

Definieren wir auch ein Repository. Es wird JpaRepository, einen der Spring Data Repository-Typen, erweitern:

interface UserRepository extends JpaRepository {}

Hier platzieren wir alle abgeleiteten Abfragemethoden.

4. Schlüsselwörter für Gleichheitsbedingungen

Genaue Gleichheit ist eine der am häufigsten verwendeten Bedingungen bei Abfragen. Wir haben verschiedene Möglichkeiten, Operatoren = oder IS in der Abfrage auszudrücken .

Wir können den Eigenschaftsnamen einfach ohne Schlüsselwort anhängen, um eine genaue Übereinstimmungsbedingung zu erhalten:

List findByName(String name);

Und wir können Is oder Equals zur besseren Lesbarkeit hinzufügen :

List findByNameIs(String name); List findByNameEquals(String name);

Diese zusätzliche Lesbarkeit ist nützlich, wenn wir stattdessen Ungleichheit ausdrücken müssen:

List findByNameIsNot(String name);

Dies ist viel besser lesbar als findByNameNot (String) !

Da die Nullgleichheit ein Sonderfall ist, sollten wir den Operator = nicht verwenden. Spring Data JPA Griffe null Parameter voreingestellt. Wenn wir also einen Nullwert für eine Gleichheitsbedingung übergeben, interpretiert Spring die Abfrage in der generierten SQL als IS NULL.

Wir können auch das Schlüsselwort IsNull verwenden , um der Abfrage IS NULL-Kriterien hinzuzufügen:

List findByNameIsNull(); List findByNameIsNotNull();

Beachten Sie, dass weder IsNull noch IsNotNull ein Methodenargument erfordern.

Es gibt auch zwei weitere Schlüsselwörter, für die keine Argumente erforderlich sind. Wir können die Schlüsselwörter True und False verwenden , um Gleichheitsbedingungen für boolesche Typen hinzuzufügen :

List findByActiveTrue(); List findByActiveFalse();

Natürlich wollen wir manchmal etwas Milderes als exakte Gleichheit. Mal sehen, was wir sonst noch tun können.

5. Schlüsselwörter für Ähnlichkeitsbedingungen

Wenn wir die Ergebnisse mit einem Muster einer Eigenschaft abfragen müssen, haben wir einige Optionen.

Mit StartingWith können wir Namen finden, die mit einem Wert beginnen :

List findByNameStartingWith(String prefix);

In etwa bedeutet dies „WO Name WIE 'Wert%' “.

Wenn wir Namen wollen, die mit einem Wert enden, dann wollen wir EndingWith :

List findByNameEndingWith(String suffix);

Oder wir können herausfinden, welche Namen einen Wert enthalten, der Folgendes enthält :

List findByNameContaining(String infix);

Beachten Sie, dass alle oben genannten Bedingungen als vordefinierte Musterausdrücke bezeichnet werden. Daher müssen wir beim Aufrufen dieser Methoden keinen % -Operator in das Argument einfügen.

Nehmen wir jedoch an, wir machen etwas Komplexeres. Angenommen, wir müssen die Benutzer abrufen, deren Namen mit a a beginnen , b enthalten und mit c enden .

Dafür können wir unser eigenes LIKE mit dem Like- Schlüsselwort hinzufügen :

List findByNameLike(String likePattern);

Und wir können dann unser LIKE-Muster abgeben, wenn wir die Methode aufrufen:

String likePattern = "a%b%c"; userRepository.findByNameLike(likePattern);

Das reicht fürs Erste für Namen. Probieren wir einige andere Werte in User aus.

6. Schlüsselwörter für Vergleichsbedingungen

Darüber hinaus können wir die Schlüsselwörter LessThan und LessThanEqual verwenden , um die Datensätze mit dem angegebenen Wert zu vergleichen, indem wir die Operatoren < und <= verwenden :

List findByAgeLessThan(Integer age); List findByAgeLessThanEqual(Integer age);

On the other hand, in the opposite situation, we can use GreaterThan and GreaterThanEqual keywords:

List findByAgeGreaterThan(Integer age); List findByAgeGreaterThanEqual(Integer age);

Or, we can find users who are between two ages with Between:

List findByAgeBetween(Integer startAge, Integer endAge);

We can also supply a collection of ages to match against using In:

List findByAgeIn(Collection ages);

Since we know the users' birthdates, we might want to query for users who were born before or after a given date. We'd use Before and After for that:

List findByBirthDateAfter(ZonedDateTime birthDate); List findByBirthDateBefore(ZonedDateTime birthDate);

7. Multiple Condition Expressions

We can combine as many expressions as we need by using And and Or keywords:

List findByNameOrBirthDate(String name, ZonedDateTime birthDate); List findByNameOrBirthDateAndActive(String name, ZonedDateTime birthDate, Boolean active);

The precedence order is And then Or, just like Java.

While Spring Data JPA imposes no limit to how many expressions we can add, we shouldn't go crazy here. Long names are unreadable and hard to maintain. For complex queries, take a look at the @Query annotation instead.

8. Sorting the Results

Next up is sorting. We could ask that the users be sorted alphabetically by their name using OrderBy:

List findByNameOrderByName(String name); List findByNameOrderByNameAsc(String name);

Ascending order is the default sorting option, but we can use Desc instead to sort them in reverse:

List findByNameOrderByNameDesc(String name);

9. findOne vs findById in a CrudRepository

The Spring team made some major changes in CrudRepository with Spring Boot 2.x. One of them is renaming findOne to findById.

Previously with Spring Boot 1.x, we'd call findOne when we wanted to retrieve an entity by its primary key:

User user = userRepository.findOne(1);

Since Spring Boot 2.x we can do the same with findById:

User user = userRepository.findById(1);

Note that the findById() method is already defined in CrudRepository for us. So we don't have to define it explicitly in custom repositories that extend CrudRepository.

10. Conclusion

In diesem Artikel haben wir den Ableitungsableitungsmechanismus in Spring Data JPA erläutert. Wir haben die Schlüsselwörter für Eigenschaftsbedingungen verwendet, um abgeleitete Abfragemethoden in Spring Data JPA-Repositorys zu schreiben.

Der Quellcode dieses Tutorials ist im Github-Projekt verfügbar.