Een gids voor DeltaSpike-gegevensmodule

1. Overzicht

Apache DeltaSpike is een project dat een verzameling CDI-extensies voor Java-projecten; het vereist een CDI-implementatie om tijdens runtime beschikbaar te zijn.

Het kan natuurlijk werken met de verschillende implementatie van CDI - JBoss Weld of OpenWebBeans. Het is ook getest op veel applicatieservers.

In deze tutorial zullen we ons concentreren op een van de bekendste en meest bruikbare - datamodules.

2. Configuratie van DeltaSpike-gegevensmodule

Apache DeltaSpike Data-module wordt gebruikt om vereenvoudig de implementatie van het repository-patroon. Het staat toe het verminderen van een standaardcode door gecentraliseerde logica te bieden voor het maken en uitvoeren van query's.

Het lijkt erg op het Spring Data-project. Om een ​​database te bevragen, moeten we een methode-declaratie definiëren (zonder implementatie) die de gedefinieerde naamgevingsconventie volgt of die bevat @Query annotatie. De implementatie wordt voor ons gedaan door de CDI-extensie.

In de volgende paragrafen bespreken we hoe u de Apache DeltaSpike Data-module in onze applicatie instelt.

2.1. Vereiste afhankelijkheden

Om de Apache DeltaSpike Data-module in de applicatie te gebruiken, moeten we de vereiste afhankelijkheden instellen.

Als Maven onze build-tool is, moeten we het volgende gebruiken:

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

Wanneer we Gradle gebruiken:

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

Apache DeltaSpike Data module artefacten zijn beschikbaar via Maven Central:

  • deltaspike-data-module-impl
  • deltaspike-data-module-api

Naar draai een applicatie met Data-module, we hebben ook een JPA- en CDI-implementaties nodig die beschikbaar zijn tijdens runtime.

Hoewel het mogelijk is om Apache DeltaSpike in een Java SE-applicatie uit te voeren, wordt het in de meeste gevallen geïmplementeerd op de applicatieserver (bijvoorbeeld Wildfly of WebSphere).

Applicatieservers hebben volledige Jakarta EE-ondersteuning, dus we hoeven niets meer te doen. In het geval van een Java SE-applicatie, moeten we deze implementaties bieden (bijvoorbeeld door afhankelijkheden toe te voegen aan de Hibernate en JBoss Weld).

Vervolgens behandelen we ook de vereiste configuratie voor EntityManager.

2.2. Entity Manager-configuratie

De Datamodule vereist EntityManager om over CDI te worden geïnjecteerd.

Dit kunnen we bereiken door gebruik te maken van een CDI-producer:

openbare klasse EntityManagerProducer {@PersistenceContext (unitName = "primair") privé EntityManager entityManager; @ApplicationScoped @Produces public EntityManager getEntityManager () {return entityManager; }}

De bovenstaande code gaat ervan uit dat we een persistentie-eenheid met naam hebben primair gedefinieerd in de persistence.xml het dossier.

Laten we hieronder een voorbeeld van een definitie bekijken:

 java: jboss / datasources / baeldung-jee7-seedDS 

De persistentie-eenheid in ons voorbeeld gebruikt het JTA-transactietype, wat betekent dat we een transactiestrategie moeten bieden die we gaan gebruiken.

2.3. Transactiestrategie

In het geval dat we het JTA-transactietype gebruiken voor onze gegevensbron, moeten we een transactiestrategie definiëren die zal worden gebruikt in de Apache DeltaSpike-opslagplaatsen. We kunnen het van binnen doen apache-deltaspike.properties bestand (onder META-INF directory):

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

Er zijn vier soorten transactiestrategieën die we kunnen definiëren:

  • BeanManagedUserTransactionStrategy
  • ResourceLocalTransactionStrategy
  • ContainerManagedTransactionStrategy
  • EnvironmentAwareTransactionStrategy

Ze implementeren allemaal org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy.

Dit was het laatste deel van de configuratie die nodig was voor onze datamodule.

Vervolgens laten we zien hoe u de repository-patroonklassen kunt implementeren.

3. Opslagplaatsklassen

Wanneer we de Apache DeltaSpike-gegevensmodule gebruiken elke abstracte klasse of interface kan een opslagplaats worden klasse.

Het enige wat we hoeven te doen isvoeg een @Repositoryannotatie met een forEntity attribuut dat de JPA-entiteit definieert die onze repository moet behandelen:

@Entity openbare klasse Gebruiker {// ...} @Repository (forEntity = User.class) openbare interface SimpleUserRepository {// ...}

of met een abstracte klasse:

@Repository (forEntity = User.class) openbare abstracte klasse SimpleUserRepository {// ...} 

Datamodule ontdekt klassen (of interfaces) met een dergelijke annotatie en verwerkt methoden die erin zitten.

Er zijn enkele mogelijkheden om de uit te voeren query te definiëren. We zullen binnenkort een voor een behandelen in de volgende secties.

4. Vraag van methode naam

De eerste mogelijkheid om definieer een query is om de methode naam te gebruiken die een gedefinieerde naamgevingsconventie volgt.

Het ziet er als volgt uit:

(Entiteit | Optioneel | Lijst | Stream) (voorvoegsel) (Eigenschap [Comparator]) {Operator-eigenschap [Comparator]} 

Vervolgens zullen we ons concentreren op elk onderdeel van deze definitie.

4.1. Retourtype

De Het retourneringstype bepaalt voornamelijk hoeveel objecten onze query kan retourneren. We kunnen geen enkel entiteitstype definiëren als een retourwaarde voor het geval onze query meer dan één resultaat zou kunnen retourneren.

De volgende methode genereert een uitzondering in het geval er meer dan één is Gebruiker met voornaam:

openbare abstracte gebruiker findByFirstName (String firstName);

Het tegenovergestelde is niet waar - we kunnen een retourwaarde definiëren als een Verzameling ook al zal het resultaat slechts een enkele entiteit zijn.

openbare abstracte verzameling findAnyByFirstName (String firstName);

Het voorvoegsel van de naam van de methode die één waarde suggereert als een retourtype (bijv. findAny) wordt onderdrukt als we de retourwaarde definiëren als Verzameling.

De bovenstaande zoekopdracht levert alles op Gebruikers met een voornaam die overeenkomt met zelfs het voorvoegsel van de methode-naam suggereert iets anders.

Dergelijke combinaties (Verzameling retourneringstype en een voorvoegsel dat één enkele waarde retourneert) moeten worden vermeden omdat de code niet intuïtief en moeilijk te begrijpen wordt.

De volgende sectie toont meer details over het voorvoegsel van de methodenaam.

4.2. Voorvoegsel voor zoekmethode

Prefix definieert de actie die we willen uitvoeren op de repository. De meest bruikbare is om entiteiten te vinden die voldoen aan bepaalde zoekcriteria.

Er zijn veel voorvoegsels voor deze actie, zoals findBy, findAny, vind alle. Raadpleeg de officiële Apache DeltaSpike-documentatie voor de gedetailleerde lijst:

openbare abstracte gebruiker findAnyByLastName (String lastName);

Er zijn echter ook andere methodesjablonen die worden gebruikt voor het tellen en verwijderen van entiteiten. Wij kunnen tellen alle rijen in een tabel:

openbare abstract int count ();

Ook, verwijderen method template bestaat die we kunnen toevoegen aan onze repository:

openbare samenvatting ongeldig verwijderen (gebruiker gebruiker);

Ondersteuning voor countBy en removeBy method prefixen zullen worden toegevoegd in de volgende versie van Apache DeltaSpike 1.9.0.

De volgende sectie laat zien hoe we meer attributen aan de queries kunnen toevoegen.

4.3. Query met veel eigenschappen

In de zoekopdracht kunnen we gebruiken veel eigenschappen gecombineerd met en operators.

openbare abstracte verzameling findByFirstNameAndLastName (String firstName, String lastName); openbare abstracte verzameling findByFirstNameOrLastName (String firstName, String lastName); 

We kunnen zoveel eigendommen combineren als we willen. Zoeken naar geneste eigenschappen is ook beschikbaar, die we hierna zullen laten zien.

4.4. Query met geneste eigenschappen

De query kan ook geneste eigenschappen gebruiken.

In het volgende voorbeeld Gebruiker entiteit heeft een adreseigenschap van het type Adres en Adres entiteit heeft een stad eigendom:

@ Entity public class Address {private String city; // ...} @Entity openbare klasse gebruiker {@OneToOne privé adresadres; // ...} openbare abstracte collectie findByAddress_city (String city);

4.5. Bestel in de vraag

DeltaSpike stelt ons in staat definieer een volgorde waarin het resultaat moet worden geretourneerd. We kunnen beide definiëren - oplopende en aflopende volgorde:

openbare abstracte lijst findAllOrderByFirstNameAsc ();

Zoals bovenal getoond we moeten doen is een deel aan de methode naam toevoegen dat de eigenschapnaam bevat waarop we willen sorteren en de korte naam voor de volgorde richting.

We kunnen veel bestellingen gemakkelijk combineren:

openbare abstracte lijst findAllOrderByFirstNameAscLastNameDesc (); 

Vervolgens laten we zien hoe u de grootte van de queryresultaten kunt beperken.

4.6. Beperk de grootte en paginering van zoekresultaten

Er zijn use-cases waarin we enkele eerste rijen uit het hele resultaat willen ophalen. Het is een zogenaamde querylimiet. Het is ook eenvoudig met de gegevensmodule:

openbare abstracte verzameling findTop2OrderByFirstNameAsc (); openbare abstracte verzameling findFirst2OrderByFirstNameAsc ();

Eerste en top kunnen door elkaar worden gebruikt.

We kunnen dan schakel query-paginering in door twee extra parameters op te geven: @EersteResult en @MaxResult:

openbare abstracte verzameling findAllOrderByFirstNameAsc (@FirstResult int start, @MaxResults int size);

We hebben al veel methoden gedefinieerd in de repository. Sommige zijn generiek en moeten één keer worden gedefinieerd en door elke repository worden gebruikt.

Apache DeltaSpike biedt enkele basistypen die we kunnen gebruiken om veel methoden uit de doos te hebben.

In de volgende sectie zullen we ons concentreren op hoe u dit moet doen.

5. Basisrepository-typen

Naar enkele basisrepository-methoden ophalen, onze repository zou het basistype van Apache DeltaSpike moeten uitbreiden. Er zijn er een paar zoals EntityRepository, FullEntityRepository, enz.:

@Repository openbare interface UserRepository breidt FullEntityRepository uit {// ...}

Of gebruik een abstracte klasse:

@Repository openbare abstracte klasse UserRepository breidt AbstractEntityRepository uit {// ...} 

De bovenstaande implementatie geeft ons veel methoden zonder extra regels code te schrijven, dus we hebben gekregen wat we wilden - we verminderen de standaardcode enorm.

In het geval dat we een basisrepository gebruiken, hoeft u geen extra forEntity waarde toe te kennen aan onze @Repository annotatie.

Wanneer we abstracte klassen gebruiken in plaats van interfaces voor onze repositories, krijgen we een extra mogelijkheid om een ​​aangepaste query te maken.

Abstracte basisrepository-klassen, bijv. AbstractEntityRepository geeft ons toegang tot velden (via getters) of hulpprogramma-methoden die we kunnen gebruiken om een ​​query te maken:

openbare lijst findByFirstName (String firstName) {return typedQuery ("selecteer u uit gebruiker u waar u.firstName =? 1") .setParameter (1, voornaam) .getResultList (); } 

In het bovenstaande voorbeeld hebben we een typedQuery utility-methode om een ​​aangepaste implementatie te maken.

De laatste mogelijkheid om een ​​query te maken is om te gebruiken @Query annotatie die we hierna zullen laten zien.

6. @Query Annotatie

De SQL uit te voeren query kan ook worden gedefinieerd met de @Query annotatie. Het lijkt erg op de Spring-oplossing. We moeten een annotatie aan de methode toevoegen met SQL-query als waarde.

Standaard is dit een JPQL-query:

@Query ("selecteer u uit gebruiker u waar u.firstName =? 1") openbare abstracte verzameling findUsersWithFirstName (String firstName); 

Net als in het bovenstaande voorbeeld kunnen we eenvoudig parameters aan de query doorgeven via een index.

Als we een query willen doorgeven via native SQL in plaats van JPQL, moeten we een extra queryattribuut definiëren - isNative met echte waarde:

@Query (value = "select * from User where firstName =? 1", isNative = true) openbare abstracte verzameling findUsersWithFirstNameNative (String firstName);

7. Conclusie

In dit artikel hebben we de basisdefinitie van Apache DeltaSpike besproken, en we hebben ons gericht op het opwindende deel - Gegevensmodule. Het lijkt erg op het Spring Data Project.

We hebben onderzocht hoe het repository-patroon kan worden geïmplementeerd. We hebben ook drie mogelijkheden geïntroduceerd om een ​​uit te voeren query te definiëren.

Zoals altijd zijn de volledige codevoorbeelden die in dit artikel worden gebruikt, beschikbaar op Github.