Spring Data JPA-forespørgsel efter eksempel

1. Introduktion

I denne vejledning skal vi lære at forespørge om data med Spring Data Query by Example API.

Først definerer vi skemaet for de data, vi vil forespørge om. Dernæst undersøger vi et par af de relevante klasser fra Spring Data. Og så løber vi gennem et par eksempler.

Lad os komme igang!

2. Testdataene

Vores testdata er en liste over passagernavne samt det sæde, de besatte.

FornavnEfternavnSæde nummer
JillSmith50
EvaJackson94
FredBloggs22
RickiBobbie36
SiyaKolisi85

3. Domæne

Lad os oprette det Spring Data Repository, vi har brug for, og give vores domæne klasse og id type.

Til at begynde med har vi modelleret vores Passager som en JPA-enhed:

@Entity-klasse Passager {@Id @GeneratedValue @Column (nullable = false) privat Lang id; @Basic (optional = false) @Column (nullable = false) private String firstName; @Basic (optional = false) @Column (nullable = false) private String efternavn; @Basic (valgfri = falsk) @Column (nullable = false) private int seatNumber; // konstruktør, getters osv.}

I stedet for at bruge JPA kunne vi have modelleret det som en anden abstraktion.

4. Forespørgsel efter eksempel API

Lad os først se på JpaRepository interface. Som vi kan se udvider det QueryByExampleExecutor interface til understøttelse af forespørgsel ved eksempel:

offentlig grænseflade JpaRepository udvider PagingAndSortingRepository, QueryByExampleExecutor {}

Denne grænseflade introducerer flere varianter af finde() metode, som vi kender fra Spring Data. Imidlertid accepterer hver metode også en forekomst af Eksempel:

offentlig grænseflade QueryByExampleExecutor {Valgfri findOne (eksempel var1); Iterabel findAll (eksempel var1); Iterabel findAll (Eksempel var1, Sort var2); Side findAll (Eksempel var1, Pageable var2); lang optælling (eksempel var1); der findes boolsk (eksempel var1); }

For det andet, den Eksempel interface udsætter metoder til at få adgang til sonde og EksempelMatcher.

Det er vigtigt at indse, at sonde er forekomsten af ​​vores Enhed:

offentlig grænseflade Eksempel {statisk org.springframework.data.domæne.eksempel på (T-probe) {returner ny TypedExample (probe, ExampleMatcher.matching ()); } statisk org.springframework.data.domæne.Eksempel på (T sonde, EksempelMatcher matcher) {returner ny TypedExempel (sonde, matcher); } T getProbe (); ExampleMatcher getMatcher (); standard Class getProbeType () {return ProxyUtils.getUserClass (this.getProbe (). getClass ()); }}

Sammenfattende er vores sonde og vores EksempelMatcher sammen angive vores forespørgsel.

5. Begrænsninger

Som alle ting har Query by Example API nogle begrænsninger. For eksempel:

  • Indlejring og gruppering af udsagn understøttes ikke, for eksempel: (fornavn =? 0 og efternavn =? 1) eller sæde nummer = ?2
  • Stringmatchning inkluderer kun nøjagtige, store og små bogstaver, starter, slutter, indeholder og regex
  • Alle andre typer end Snor er kun eksakte match

Nu hvor vi er lidt mere fortrolige med API'en og dens begrænsninger, lad os dykke ned i nogle eksempler.

6. Eksempler

6.1. Skift mellem store og små bogstaver

Lad os starte med et simpelt eksempel og tale om standardadfærden:

@Test offentligt ugyldigt givenPassengers_whenFindByExample_thenExpectedReturned () {Eksempeleksempel = eksempel.af (Passenger.from ("Fred", "Bloggs", null)); Valgfri faktisk = repository.findOne (eksempel); assertTrue (actual.isPresent ()); assertEquals (Passenger.from ("Fred", "Bloggs", 22), actual.get ()); }

Især det statiske Eksempel. Af () metoden bygger en Eksempel ved brug af ExampleMatcher.matching ().

Med andre ord, et nøjagtigt match udføres på alle ejendomme, der ikke er nul af Passager. Således er matchningen store og små bogstaver Snor ejendomme.

Det ville dog ikke være for nyttigt, hvis alt, hvad vi kunne gøre, var et nøjagtigt match på alle egenskaber, der ikke er nul.

Det er her, EksempelMatcher kommer ind. Ved at bygge vores egne EksempelMatcher, kan vi tilpasse adfærden, så den passer til vores behov.

6.2. Sag-ufølsom matchning

Med det i tankerne, lad os se på et andet eksempel, denne gang ved hjælp af medIgnoreCase () for at opnå store og små bogstaver:

@Test offentligt ugyldigt givenPassengers_whenFindByExampleCaseInsensitiveMatcher_thenExpectedReturned () {ExampleMatcher caseInsensitiveExampleMatcher = ExampleMatcher.matchingAll (). WithIgnoreCase (); Eksempeleksempel = Example.of (Passenger.from ("fred", "bloggs", null), caseInsensitiveExampleMatcher); Valgfri faktisk = repository.findOne (eksempel); assertTrue (actual.isPresent ()); assertEquals (Passenger.from ("Fred", "Bloggs", 22), actual.get ()); }

I dette eksempel skal du bemærke, at vi først ringede ExampleMatcher.matchingAll () - det har samme adfærd som ExampleMatcher.matching (), som vi brugte i det foregående eksempel.

6.3. Custom Matching

Det kan vi også afstem opførelsen af ​​vores matcher pr. ejendom og matche enhver ejendom, der bruger ExampleMatcher.matchingAny ():

@ Test offentligt ugyldigt givenPassengers_whenFindByExampleCustomMatcher_thenExpectedReturned () {Passenger jill = Passenger.from ("Jill", "Smith", 50); Passageraften = Passenger.from ("Eve", "Jackson", 95); Passager fred = Passenger.from ("Fred", "Bloggs", 22); Passager siya = Passenger.from ("Siya", "Kolisi", 85); Passager ricki = Passenger.from ("Ricki", "Bobbie", 36); ExampleMatcher customExampleMatcher = ExampleMatcher.matchingAny () .withMatcher ("firstName", ExampleMatcher.GenericPropertyMatchers.contains (). IgnoreCase ()) .withMatcher ("lastName", ExampleMatcher.GenericPropertyMatchers.contains ()). IgnorCase Eksempeleksempel = eksempel.of (Passenger.from ("e", "s", null), customExampleMatcher); Listepassagerer = repository.findAll (eksempel); hævder, at (passagerer, indeholder (jill, aften, fred, siya)); hævder, at (passagerer, ikke (indeholder (Ricki))); }

6.4. Ignorer egenskaber

På den anden side ønsker vi måske kun forespørgsel på en delmængde af vores ejendomme.

Vi opnår dette ved at ignorere nogle egenskaber ved hjælp af ExampleMatcher.ignorePaths (streng ... stier):

@Test offentlig ugyldighed givenPassengers_whenFindByIgnoringMatcher_thenExpectedReturned () {Passenger jill = Passenger.from ("Jill", "Smith", 50); Passageraften = Passenger.from ("Eve", "Jackson", 95); Passager fred = Passenger.from ("Fred", "Bloggs", 22); Passager siya = Passenger.from ("Siya", "Kolisi", 85); Passager ricki = Passenger.from ("Ricki", "Bobbie", 36); ExampleMatcher ignoringExampleMatcher = ExampleMatcher.matchingAny () .withMatcher ("lastName", ExampleMatcher.GenericPropertyMatchers.startsWith (). IgnoreCase ()) .withIgnorePaths ("firstName", "seatNumber"); Eksempeleksempel = Eksempel.af (Passenger.from (null, "b", null), ignorererExampleMatcher); Listepassagerer = repository.findAll (eksempel); hævder, at (passagerer, indeholder (fred, ricki)); hævde, at (passagerer, ikke (indeholder (jill)); hævder, at (passagerer, ikke (indeholder (aften)); hævder, at (passagerer, ikke (indeholder (siya));}

7. Konklusion

I denne artikel har vi demonstreret, hvordan man bruger Query by Example API.

Vi har demonstreret, hvordan man bruger Eksempel og EksempelMatcher sammen med QueryByExampleExecutor interface til forespørgsel på en tabel ved hjælp af et eksempel på en datainstans.

Afslutningsvis kan du finde koden over på GitHub.