Spring Data JPA Query by Example

1. Inleiding

In deze tutorial gaan we dat doen leer hoe u gegevens opvraagt ​​met de Spring Data Query by Example API.

Eerst definiëren we het schema van de gegevens die we willen opvragen. Vervolgens zullen we enkele van de relevante klassen uit Spring Data bekijken. En dan zullen we een paar voorbeelden doornemen.

Laten we beginnen!

2. De testgegevens

Onze testgegevens zijn een lijst met passagiersnamen en de stoel die ze bezetten.

VoornaamAchternaamStoelnummer
JillSmith50
VooravondJackson94
FredBloggs22
RickiBobbie36
SiyaKolisi85

3. Domein

Laten we de Spring Data Repository maken die we nodig hebben en onze domeinklasse en id-type opgeven.

Om te beginnen hebben we onze Passagier als PPV-entiteit:

@Entity class Passenger {@Id @GeneratedValue @Column (nullable = false) privé Lange id; @Basic (optioneel = false) @Column (nullable = false) private String firstName; @Basic (optioneel = false) @Column (nullable = false) private String lastName; @Basic (optioneel = false) @Column (nullable = false) private int seatNumber; // constructor, getters etc.}

In plaats van JPA te gebruiken, hadden we het als een andere abstractie kunnen modelleren.

4. Query door voorbeeld-API

Laten we eerst eens kijken naar het JpaRepository koppel. Zoals we kunnen zien, breidt het de QueryByExampleExecutor interface ter ondersteuning van vraag door voorbeeld:

openbare interface JpaRepository breidt PagingAndSortingRepository, QueryByExampleExecutor {} uit

Deze interface introduceert meer varianten van de vind() methode die we kennen van Spring Data. Elke methode accepteert echter ook een exemplaar van Voorbeeld:

openbare interface QueryByExampleExecutor {Optioneel findOne (voorbeeld var1); Iterable findAll (voorbeeld var1); Iterable findAll (Voorbeeld var1, Sort var2); Page findAll (Voorbeeld var1, Pageable var2); lange telling (voorbeeld var1); boolean bestaat (voorbeeld var1); }

Ten tweede, de Voorbeeld interface onthult methoden om toegang te krijgen tot het sonde en de VoorbeeldMatcher.

Het is belangrijk om te beseffen dat de sonde is het voorbeeld van onze Entiteit:

openbare interface Voorbeeld {statisch org.springframework.data.domain.Example van (T-sonde) {retourneer nieuw TypedExample (sonde, ExampleMatcher.matching ()); } statische org.springframework.data.domain.Example van (T-sonde, ExampleMatcher-matcher) {return new TypedExample (sonde, matcher); } T getProbe (); VoorbeeldMatcher getMatcher (); standaardklasse getProbeType () {retourneer ProxyUtils.getUserClass (this.getProbe (). getClass ()); }}

Samengevat, onze sonde en onze VoorbeeldMatcher specificeer samen onze vraag.

5. Beperkingen

Zoals alle dingen heeft de Query by Example-API enkele beperkingen. Bijvoorbeeld:

  • Instructies voor nesten en groeperen worden niet ondersteund, bijvoorbeeld: (Voornaam =? 0 en achternaam =? 1) of stoelnummer = ?2
  • Tekenreeksovereenkomsten omvatten alleen exact, niet hoofdlettergevoelig, begin, einde, bevat en regex
  • Alle soorten behalve Draad zijn alleen exact gelijk

Nu we wat meer bekend zijn met de API en zijn beperkingen, laten we enkele voorbeelden bekijken.

6. Voorbeelden

6.1. Hoofdlettergevoelige afstemming

Laten we beginnen met een eenvoudig voorbeeld en het hebben over het standaardgedrag:

@Test openbare ongeldig gegevenPassengers_whenFindByExample_thenExpectedReturned () {Voorbeeld voorbeeld = Voorbeeld.of (Passenger.from ("Fred", "Bloggs", null)); Optioneel actual = repository.findOne (voorbeeld); assertTrue (actual.isPresent ()); assertEquals (Passenger.from ("Fred", "Bloggs", 22), actual.get ()); }

Met name de statische Voorbeeld van() methode bouwt een Voorbeeld gebruik makend van VoorbeeldMatcher.matching ().

Met andere woorden, er wordt een exacte overeenkomst uitgevoerd op alle niet-null-eigenschappen van Passagier. Het matchen is dus hoofdlettergevoelig op Draad eigendommen.

Het zou echter niet zo handig zijn als we alleen een exacte match zouden kunnen doen voor alle niet-null-eigenschappen.

Dit is waar de VoorbeeldMatcher komt binnen. Door onze eigen te bouwen VoorbeeldMatcherkunnen we het gedrag aanpassen aan onze behoeften.

6.2. Hoofdletterongevoelige afstemming

Laten we met dat in gedachten eens naar een ander voorbeeld kijken, deze keer met withIgnoreCase () om hoofdletterongevoelige afstemming te bereiken:

@Test openbare ongeldig gegevenPassengers_whenFindByExampleCaseInsensitiveMatcher_thenExpectedReturned () {ExampleMatcher caseInsensitiveExampleMatcher = ExampleMatcher.matchingAll (). WithIgnoreCase (); Voorbeeld example = Example.of (Passenger.from ("fred", "bloggs", null), caseInsensitiveExampleMatcher); Optioneel actual = repository.findOne (voorbeeld); assertTrue (actual.isPresent ()); assertEquals (Passenger.from ("Fred", "Bloggs", 22), actual.get ()); }

Merk in dit voorbeeld op dat we voor het eerst hebben gebeld VoorbeeldMatcher.matchingAll () - het heeft hetzelfde gedrag als VoorbeeldMatcher.matching (), die we in het vorige voorbeeld hebben gebruikt.

6.3. Aangepaste matching

We kunnen ook stem het gedrag van onze matcher af per eigenschap en match elke eigenschap met VoorbeeldMatcher.matchingAny ():

@Test openbare ongeldig gegevenPassengers_whenFindByExampleCustomMatcher_thenExpectedReturned () {Passenger jill = Passenger.from ("Jill", "Smith", 50); Passenger eve = Passenger.from ("Eve", "Jackson", 95); Passenger fred = Passenger.from ("Fred", "Bloggs", 22); Passenger siya = Passenger.from ("Siya", "Kolisi", 85); Passenger ricki = Passenger.from ("Ricki", "Bobbie", 36); VoorbeeldMatcher customExampleMatcher = ExampleMatcher.matchingAny () .withMatcher ("firstName", ExampleMatcher.GenericPropertyMatchers.contains (). IgnoreCase ()) .withMatcher ("lastName", ExampleMatcher.GenericPropertyMatchers.contains (). IgnoreCase ()); Voorbeeld voorbeeld = Voorbeeld.of (Passenger.from ("e", "s", null), customExampleMatcher); Lijst passagiers = repository.findAll (voorbeeld); assertThat (passagiers, bevat (jill, eve, fred, siya)); assertThat (passagiers, niet (bevat (ricki))); }

6.4. Eigenschappen negeren

Aan de andere kant willen we misschien ook alleen maar query op een subset van onze eigenschappen.

We bereiken dit door enkele eigenschappen te negeren met VoorbeeldMatcher.ignorePaths (tekenreeks… paden):

@Test openbare ongeldig gegevenPassengers_whenFindByIgnoringMatcher_thenExpectedReturned () {Passenger jill = Passenger.from ("Jill", "Smith", 50); Passenger eve = Passenger.from ("Eve", "Jackson", 95); Passenger fred = Passenger.from ("Fred", "Bloggs", 22); Passenger siya = Passenger.from ("Siya", "Kolisi", 85); Passenger ricki = Passenger.from ("Ricki", "Bobbie", 36); ExampleMatcher ignoringExampleMatcher = ExampleMatcher.matchingAny () .withMatcher ("lastName", ExampleMatcher.GenericPropertyMatchers.startsWith (). IgnoreCase ()) .withIgnorePaths ("firstName", "seatNumber"); Voorbeeld example = Example.of (Passenger.from (null, "b", null), ignoringExampleMatcher); Lijst passagiers = repository.findAll (voorbeeld); assertThat (passagiers, bevat (fred, ricki)); assertThat (passagiers, niet (bevat (jill)); assertThat (passagiers, niet (bevat (eve)); assertThat (passagiers, niet (bevat (siya));}

7. Conclusie

In dit artikel hebben we laten zien hoe u de Query by Example-API kunt gebruiken.

We hebben laten zien hoe u Voorbeeld en VoorbeeldMatcher samen met de QueryByExampleExecutor interface om een ​​tabel op te vragen met behulp van een voorbeeldgegevensinstantie.

Tot slot kun je de code vinden op GitHub.


$config[zx-auto] not found$config[zx-overlay] not found