En guide til DeltaSpike datamodul

1. Oversigt

Apache DeltaSpike er et projekt, der giver en samling af CDI-udvidelser til Java-projekter; det kræver, at en CDI-implementering er tilgængelig ved kørsel.

Selvfølgelig kan det arbejde med den forskellige implementering af CDI - JBoss Weld eller OpenWebBeans. Det er også testet på mange applikationsservere.

I denne vejledning fokuserer vi på en af ​​de mest kendte og nyttige - Datamodul.

2. Opsætning af DeltaSpike datamodul

Apache DeltaSpike Data-modul bruges til forenkle implementeringen af ​​depotmønsteret. Det tillader reducere en kedelpladekode ved at tilvejebringe centraliseret logik til oprettelse og udførelse af forespørgsler.

Det ligner meget Spring Data-projektet. For at forespørge en database skal vi definere en metodedeklaration (uden implementering), der følger den definerede navngivningskonvention eller som indeholder @Forespørgsel kommentar. Implementeringen vil blive gjort for os af CDI-udvidelsen.

I de næste underafsnit dækker vi, hvordan du konfigurerer Apache DeltaSpike Data-modulet i vores applikation.

2.1. Nødvendige afhængigheder

For at bruge Apache DeltaSpike Data-modul i applikationen er vi nødt til at konfigurere de nødvendige afhængigheder.

Når Maven er vores byggeværktøj, skal vi bruge:

 org.apache.deltaspike.modules deltaspike-data-module-api 1.8.2 kompilere org.apache.deltaspike.modules deltaspike-data-module-impl 1.8.2 runtime 

Når vi bruger Gradle:

runtime 'org.apache.deltaspike.modules: deltaspike-data-module-impl' kompilere 'org.apache.deltaspike.modules: deltaspike-data-module-api' 

Apache DeltaSpike Data-modul artefakter er tilgængelige på Maven Central:

  • deltaspike-data-modul-impl
  • deltaspike-data-modul-api

Til køre et program med datamodul, har vi også brug for en JPA- og CDI-implementering tilgængelig ved kørsel.

Selvom det er muligt at køre Apache DeltaSpike i Java SE-applikationen, vil det i de fleste tilfælde blive implementeret på applikationsserveren (f.eks. Wildfly eller WebSphere).

Applikationsservere har fuld Jakarta EE-support, så vi behøver ikke gøre noget mere. I tilfælde af Java SE-applikation er vi nødt til at levere disse implementeringer (f.eks. Ved at tilføje afhængigheder til Hibernate og JBoss Weld).

Dernæst dækker vi også den nødvendige konfiguration til EntityManager.

2.2. Entity Manager-konfiguration

Det Datamodul kræver EntityManager skal injiceres over CDI.

Vi kan opnå dette ved at bruge en CDI-producent:

public class EntityManagerProducer {@PersistenceContext (unitName = "primary") private EntityManager entityManager; @ApplicationScoped @Produces offentlig EntityManager getEntityManager () {return entityManager; }}

Ovenstående kode forudsætter, at vi har enheden med navn primær defineret i persistence.xml fil.

Lad os se nedenfor som et eksempel på definition:

 java: jboss / datakilder / baeldung-jee7-seedDS 

Vedholdenhedsenheden i vores eksempel bruger JTA-transaktionstype, hvilket betyder, at vi skal levere en transaktionsstrategi, vi skal bruge.

2.3. Transaktionsstrategi

Hvis vi bruger JTA-transaktionstype til vores datakilde, er vi nødt til at definere transaktionsstrategi, der skal bruges i Apache DeltaSpike repositories. Vi kan gøre det indeni apache-deltaspike.properties fil (under META-INF vejviser):

globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy = org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy

Der er fire typer transaktionsstrategier, vi kan definere:

  • BeanManagedUserTransactionStrategy
  • ResourceLocalTransactionStrategy
  • ContainerManagedTransactionStrategy
  • EnvironmentAwareTransactionStrategy

Alle implementerer dem org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy.

Dette var den sidste del af den konfiguration, der kræves til vores datamodul.

Dernæst viser vi, hvordan vi implementerer lagerkassemønsterklasser.

3. Lagerklasser

Når vi bruger Apache DeltaSpike datamodul enhver abstrakt klasse eller grænseflade kan blive et lager klasse.

Alt hvad vi skal gøre er attilføj en @Repositorykommentar med en forEnhed attribut, der definerer JPA-enhed, som vores arkiv skal håndtere:

@Entity public class User {// ...} @Repository (forEntity = User.class) offentlig grænseflade SimpleUserRepository {// ...}

eller med en abstrakt klasse:

@Repository (forEntity = User.class) offentlig abstrakt klasse SimpleUserRepository {// ...} 

Datamodul opdager klasser (eller grænseflader) med en sådan kommentar, og det behandler metoder, der er indeni.

Der er få muligheder for at definere den forespørgsel, der skal udføres. Vi dækker en efter en kort tid i de følgende afsnit.

4. Forespørgsel fra metodens navn

Den første mulighed for at definere en forespørgsel er at bruge metodenavn, der følger en defineret navngivningskonvention.

Det ser ud som nedenfor:

(Enhed | Valgfri | Liste | Strøm) (præfiks) (Ejendom [Komparator]) {Operatørsejendom [Komparator]} 

Dernæst fokuserer vi på hver del af denne definition.

4.1. Returtype

Det return type definerer hovedsageligt hvor mange objekter vores forespørgsel kan returnere. Vi kan ikke definere en enkelt enhedstype som en returværdi, hvis vores forespørgsel muligvis returnerer mere end et resultat.

Den følgende metode kaster en undtagelse, hvis der er mere end en Bruger med fornavn:

offentlig abstrakt Bruger findByFirstName (streng fornavn);

Det modsatte er ikke sandt - vi kan definere en returværdi som en Kollektion selvom resultatet kun bliver en enkelt enhed.

offentlig abstrakt samling findAnyByFirstName (streng fornavn);

Metodenavnets præfiks, der antyder en værdi som en returtype (f.eks. find nogen) undertrykkes, hvis vi definerer returværdien som Kollektion.

Ovenstående forespørgsel returnerer alle Brugere med et fornavn, der matcher selv metodenavnets præfiks antyder noget andet.

Sådanne kombinationer (Kollektion return type og et præfiks, der antyder en enkelt værdi returnering) bør undgås, fordi koden ikke bliver intuitiv og svær at forstå.

Det næste afsnit viser flere detaljer om metodenavnets præfiks.

4.2. Præfiks for forespørgselsmetode

Præfiks definerer den handling, vi vil udføre på lageret. Den mest nyttige er at finde enheder, der matcher givne søgekriterier.

Der er mange præfikser til denne handling som findBy, find nogen, findAlle. For den detaljerede liste, se venligst den officielle Apache DeltaSpike-dokumentation:

offentlig abstrakt Bruger findAnyByLastName (streng efternavn);

Der er dog også andre metodeskabeloner, der bruges til at tælle og fjerne enheder. Vi kan tælle alle rækker i en tabel:

offentlig abstrakt int count ();

Også, fjerne der findes en metodeskabelon, som vi kan tilføje i vores lager:

offentlig abstrakt ugyldig fjernelse (brugerbruger);

Støtte for countBy og removeBy metode præfikser tilføjes i den næste version af Apache DeltaSpike 1.9.0.

Det næste afsnit viser, hvordan vi kan tilføje flere attributter til forespørgslerne.

4.3. Forespørgsel med mange egenskaber

I forespørgslen kan vi bruge mange ejendomme kombineret med og operatører.

offentlig abstrakt samling findByFirstNameAndLastName (streng fornavn, streng efternavn); offentlig abstrakt samling findByFirstNameOrLastName (streng fornavn, streng efternavn); 

Vi kan kombinere så mange egenskaber, som vi vil. Søgning efter indlejrede ejendomme er også tilgængelig, som vi viser næste.

4.4. Forespørgsel med indlejrede egenskaber

Det forespørgsel kan også bruge indlejrede egenskaber.

I det følgende eksempel Bruger enhed har en adresseegenskab af typen Adresse og Adresse enhed har en by ejendom:

@Entity offentlig klasse Adresse {privat strengby; // ...} @Entity offentlig klasse bruger {@OneToOne privat adresse adresse; // ...} offentlig abstrakt samling findByAddress_city (strengby);

4.5. Bestil i forespørgslen

DeltaSpike tillader os at definere en rækkefølge, hvor resultatet skal returneres. Vi kan definere både - stigende og faldende rækkefølge:

offentlig abstrakt Liste findAllOrderByFirstNameAsc ();

Som vist frem for alt vi skal gøre er at tilføje en del til metodens navn, der indeholder egenskabsnavnet, vi vil sortere efter, og det korte navn til ordreretningen.

Vi kan nemt kombinere mange ordrer:

offentlig abstrakt Liste findAllOrderByFirstNameAscLastNameDesc (); 

Dernæst viser vi, hvordan vi begrænser størrelsen på forespørgselsresultatet.

4.6. Begræns forespørgselsresultatstørrelse og paginering

Der er brugstilfælde, når vi vil hente nogle få første rækker fra hele resultatet. Det er den såkaldte forespørgselsgrænse. Det er også ligetil med datamodul:

offentlig abstrakt samling findTop2OrderByFirstNameAsc (); offentlig abstrakt samling findFirst2OrderByFirstNameAsc ();

Først og top kan bruges om hverandre.

Det kan vi så aktiver forespørgselsinddeling ved at angive to yderligere parametre: @FirstResult og @MaxResult:

offentlig abstrakt samling findAllOrderByFirstNameAsc (@FirstResult int start, @MaxResults int størrelse);

Vi definerede allerede mange metoder i lageret. Nogle af dem er generiske og skal defineres en gang og bruges af hvert arkiv.

Apache DeltaSpike tilbyder få basistyper, som vi kan bruge til at have mange metoder ud af kassen.

I det næste afsnit fokuserer vi på, hvordan du gør dette.

5. Grundlæggende arkivtyper

Til få nogle grundlæggende opbevaringsmetoder, vores opbevaringssted skal udvide grundlæggende type leveret af Apache DeltaSpike. Der er nogle af dem som EntityRepository, FullEntityRepository, etc.:

@Repository offentlig grænseflade UserRepository udvider FullEntityRepository {// ...}

Eller ved hjælp af en abstrakt klasse:

@Repository offentlig abstrakt klasse UserRepository udvider AbstractEntityRepository {// ...} 

Ovenstående implementering giver os en masse metoder uden at skrive yderligere kodelinjer, så vi fik det, vi ønskede - vi reducerer kedelpladekoden massivt.

Hvis vi bruger basebasertype, er der ingen grund til at sende en ekstra forEnhed tilskriver værdi til vores @Repository kommentar.

Når vi bruger abstrakte klasser i stedet for grænseflader til vores arkiver, får vi en ekstra mulighed for at oprette en brugerdefineret forespørgsel.

Abstrakte basislagerklasser, f.eks. AbstractEntityRepository giver os adgang til felter (via getters) eller hjælpemetoder, som vi kan bruge til at oprette en forespørgsel:

offentlig liste findByFirstName (streng fornavn) {return typedQuery ("vælg u fra bruger u hvor u.firstName =? 1") .setParameter (1, fornavn) .getResultList (); } 

I ovenstående eksempel brugte vi a typedQuery hjælpemetode til at oprette en brugerdefineret implementering.

Den sidste mulighed for at oprette en forespørgsel er at bruge @Forespørgsel kommentar, som vi viser næste.

6. @Forespørgsel Kommentar

SQL forespørgsel, der skal udføres, kan også defineres med @Forespørgsel kommentar. Det ligner meget på Spring-løsningen. Vi er nødt til at tilføje en kommentar til metoden med SQL-forespørgsel som værdi.

Som standard er dette en JPQL-forespørgsel:

@Query ("vælg u fra bruger u hvor u.firstName =? 1") offentlig abstrakt samling findUsersWithFirstName (streng fornavn); 

Som i ovenstående eksempel kan vi nemt overføre parametre til forespørgslen via et indeks.

Hvis vi ønsker at sende forespørgsel via native SQL i stedet for JPQL, skal vi definere yderligere forespørgselsattribut - isNative med ægte værdi:

@Query (værdi = "vælg * fra bruger, hvor firstName =? 1", isNative = true) offentlig abstrakt samling findUsersWithFirstNameNative (streng fornavn);

7. Konklusion

I denne artikel dækkede vi den grundlæggende definition af Apache DeltaSpike, og vi fokuserede på den spændende del - datamodul. Det ligner meget på Spring Data Project.

Vi undersøgte, hvordan man implementerer depotmønsteret. Vi introducerede også tre muligheder for, hvordan man definerer en forespørgsel, der skal udføres.

Som altid er de komplette kodeeksempler, der bruges i denne artikel, tilgængelige på Github.


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