Spring Data JPA Query by Example

1. Introduksjon

I denne opplæringen skal vi lære å spørre om data med Spring Data Query by Example API.

Først definerer vi skjemaet for dataene vi ønsker å spørre om. Deretter vil vi undersøke noen av de aktuelle klassene fra Spring Data. Og så vil vi gå gjennom noen få eksempler.

La oss komme i gang!

2. Testdataene

Testdataene våre er en liste over passasjernavn, samt setet de okkuperte.

FornavnEtternavnSetenummer
JillSmith50
EvaJackson94
FredBloggs22
RickiBobbie36
SiyaKolisi85

3. Domene

La oss opprette Spring Data Repository vi trenger og gi domeneklassen og id-typen.

Til å begynne med har vi modellert vår Passasjer som en JPA-enhet:

@Entity class Passenger {@Id @GeneratedValue @Column (nullable = false) private Lang id; @Basic (optional = false) @Column (nullable = false) private String fornavn; @Basic (optional = false) @Column (nullable = false) private String etternavn; @Basic (valgfritt = false) @Column (nullable = false) private int seatNumber; // konstruktør, getters osv.}

I stedet for å bruke JPA, kunne vi ha modellert det som en annen abstraksjon.

4. Spørring etter eksempel API

For det første, la oss ta en titt på JpaRepository grensesnitt. Som vi kan se utvider det QueryByExampleExecutor grensesnitt for å støtte spørring ved eksempel:

offentlig grensesnitt JpaRepository utvider PagingAndSortingRepository, QueryByExampleExecutor {}

Dette grensesnittet introduserer flere varianter av finne() metoden som vi er kjent med fra Spring Data. Imidlertid aksepterer hver metode også en forekomst av Eksempel:

offentlig grensesnitt QueryByExampleExecutor {Valgfri findOne (eksempel var1); Iterable findAll (eksempel var1); Iterable findAll (Eksempel var1, Sorter var2); Side findAll (Eksempel var1, Sidbar var2); lang telling (Eksempel var1); boolsk eksisterer (eksempel var1); }

For det andre, den Eksempel grensesnittet viser metoder for å få tilgang til sonde og EksempelMatcher.

Det er viktig å innse at sonde er forekomsten av vår Enhet:

offentlig grensesnitt Eksempel {static org.springframework.data.domain.Example of (T probe) {return new TypedExample (probe, ExampleMatcher.matching ()); } statisk org.springframework.data.domain.Example of (T probe, ExampleMatcher matcher) {return new TypedExample (probe, matcher); } T getProbe (); ExampleMatcher getMatcher (); standard Class getProbeType () {return ProxyUtils.getUserClass (this.getProbe (). getClass ()); }}

Oppsummert, vår sonde og vår EksempelMatcher sammen spesifisere spørringen vår.

5. Begrensninger

Som alle ting har Query by Example API noen begrensninger. For eksempel:

  • Nest- og grupperingsuttalelser støttes ikke, for eksempel: (fornavn =? 0 og etternavn =? 1) eller setenummer = ?2
  • Strengmatching inkluderer bare eksakt, store og små bokstaver, starter, slutter, inneholder og regex
  • Alle typer andre enn String er bare eksakt samsvar

Nå som vi er litt mer kjent med API og dens begrensninger, la oss dykke inn i noen eksempler.

6. Eksempler

6.1. Skift mellom store og små bokstaver

La oss starte med et enkelt eksempel og snakke om standardadferd:

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

Spesielt det statiske Eksempel av() metoden bygger en Eksempel ved hjelp av ExampleMatcher.matching ().

Med andre ord, en nøyaktig samsvar vil bli utført på alle eiendommer som ikke er null av Passasjer. Dermed er samsvaret mellom store og små bokstaver på String eiendommer.

Det ville imidlertid ikke være for nyttig hvis alt vi kunne gjøre var en nøyaktig samsvar med alle ikke-null egenskaper.

Dette er hvor EksempelMatcher kommer inn. Ved å bygge våre egne EksempelMatcher, kan vi tilpasse atferden etter våre behov.

6.2. Tilfelle-ufølsom samsvar

Med det i tankene, la oss ta en titt på et annet eksempel, denne gangen ved hjelp av withIgnoreCase () for å oppnå store og små bokstaver:

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

Legg merke til at vi først ringte i dette eksemplet ExampleMatcher.matchingAll () - den har samme oppførsel som ExampleMatcher.matching (), som vi brukte i forrige eksempel.

6.3. Egendefinert samsvar

Vi kan også juster oppførselen til matcheren vår per eiendom og matche enhver eiendom som bruker ExampleMatcher.matchingAny ():

@Test offentlig ugyldig givenPassengers_whenFindByExampleCustomMatcher_thenExpectedReturned () {Passenger jill = Passenger.from ("Jill", "Smith", 50); Passasjeraften = Passenger.from ("Eve", "Jackson", 95); Passasjer fred = Passenger.from ("Fred", "Bloggs", 22); Passasjer siya = Passenger.from ("Siya", "Kolisi", 85); Passasjericki = 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); Listepassasjerer = repository.findAll (eksempel); assertThat (passasjerer, inneholder (jill, eve, fred, siya)); hevder at (passasjerer, ikke (inneholder (ricki))); }

6.4. Ignorerer egenskaper

På den annen side vil vi kanskje også bare spørring på en delmengde av eiendommene våre.

Vi oppnår dette ved å ignorere noen egenskaper ved hjelp av ExampleMatcher.ignorePaths (streng ... stier):

@Test offentlig ugyldig givenPassengers_whenFindByIgnoringMatcher_thenExpectedReturned () {Passenger jill = Passenger.from ("Jill", "Smith", 50); Passenger Eve = Passenger.from ("Eve", "Jackson", 95); Passasjer fred = Passenger.from ("Fred", "Bloggs", 22); Passasjer 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"); Eksempeleksempel = Eksempel.of (Passenger.from (null, "b", null), ignorererExampleMatcher); Listepassasjerer = repository.findAll (eksempel); assertThat (passasjerer, inneholder (fred, ricki)); assertThat (passasjerer, ikke (inneholder (jill)); assertThat (passasjerer, ikke (inneholder (eve)); assertThat (passasjerer, ikke (inneholder (siya));}

7. Konklusjon

I denne artikkelen har vi demonstrert hvordan du bruker Query by Example API.

Vi har demonstrert hvordan du bruker Eksempel og EksempelMatcher sammen med QueryByExampleExecutor grensesnitt for å spørre en tabell ved hjelp av et eksempel på dataforekomster

Avslutningsvis kan du finne koden på GitHub.


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