Inleiding tot Spring Data JPA

1. Overzicht

Dit artikel zal zich concentreren op Spring Data JPA introduceren in een Spring-project en het volledig configureren van de persistentielaag. Zie dit artikel voor een stapsgewijze introductie over het instellen van de Spring-context met behulp van op Java gebaseerde configuratie en de basis Maven pom voor het project.

2. De Spring Data Generated DAO - Geen DAO-implementaties meer

Zoals we in een eerder artikel hebben besproken, bestaat de DAO-laag meestal uit veel standaardcode die kan en moet worden vereenvoudigd. De voordelen van een dergelijke vereenvoudiging zijn talrijk: een afname van het aantal artefacten dat we moeten definiëren en onderhouden, consistentie van datatoegangspatronen en consistentie van configuratie.

Spring Data neemt deze vereenvoudiging een stap voorwaarts en maakt het mogelijk om de DAO-implementaties volledig te verwijderen. De interface van de DAO is nu het enige artefact dat we expliciet moeten definiëren.

Om het Spring Data-programmeermodel met JPA te kunnen gebruiken, moet een DAO-interface de JPA-specificatie uitbreiden Opslagplaats koppel - JpaRepository. Hierdoor kan Spring Data deze interface vinden en er automatisch een implementatie voor maken.

Door de interface uit te breiden, krijgen we de meest relevante CRUD-methoden voor standaard gegevenstoegang beschikbaar in een standaard DAO.

3. Aangepaste toegangsmethode en zoekopdrachten

Zoals besproken, door een van de Opslagplaats interfaces, heeft de DAO al enkele basis CRUD-methoden (en queries) gedefinieerd en geïmplementeerd.

Om meer specifieke toegangsmethoden te definiëren, ondersteunt Spring JPA nogal wat opties:

  • gewoon definieer een nieuwe methode in de interface
  • verstrek de daadwerkelijke JPQL-zoekopdracht door de @Query annotatie
  • gebruik de meer geavanceerde Specificatie en Querydsl-ondersteuning in Spring Data
  • bepalen aangepaste zoekopdrachten via JPA Named Queries

De derde optie - de Specificaties en Querydsl-ondersteuning - is vergelijkbaar met JPA-criteria, maar gebruikt een meer flexibele en handige API. Dit maakt de hele operatie veel leesbaarder en herbruikbaar. De voordelen van deze API zullen duidelijker worden bij het omgaan met een groot aantal vaste zoekopdrachten, omdat we deze mogelijk beknopter kunnen uitdrukken door een kleiner aantal herbruikbare blokken.

Deze laatste optie heeft het nadeel dat het ofwel XML betreft ofwel de domeinklasse belast met de queries.

3.1. Automatische aangepaste zoekopdrachten

Wanneer Spring Data een nieuw Opslagplaats implementatie, analyseert het alle methoden die door de interfaces zijn gedefinieerd en probeert het automatisch query's genereren op basis van de namen van methoden. Hoewel dit enkele beperkingen heeft, is het een zeer krachtige en elegante manier om met weinig moeite nieuwe aangepaste toegangsmethoden te definiëren.

Laten we naar een voorbeeld kijken: als de entiteit een naam veld (en de Java Bean-standaard getName en setName methoden), we zullen de findByName methode in de DAO-interface; dit genereert automatisch de juiste zoekopdracht:

openbare interface IFooDAO breidt JpaRepository {Foo findByName (String naam) uit; }

Dit is een relatief eenvoudig voorbeeld. Het mechanisme voor het maken van query's ondersteunt een veel grotere set trefwoorden.

In het geval dat de parser de eigenschap niet kan matchen met het domeinobjectveld, zien we de volgende uitzondering:

java.lang.IllegalArgumentException: geen eigenschapnaam gevonden voor type class com.baeldung.spring.data.persistence.model.Foo

3.2. Handmatige aangepaste zoekopdrachten

Laten we nu eens kijken naar een aangepaste query die we zullen definiëren via de @Query annotatie:

@Query ("SELECTEER f VAN Foo f WHERE LOWER (f.name) = LOWER (: naam)") Foo retrieveByName (@Param ("naam") Stringnaam);

Voor nog meer fijnmazige controle over het maken van query's, zoals het gebruik van benoemde parameters of het wijzigen van bestaande query's, is de referentie een goede plek om te beginnen.

4. Transactieconfiguratie

De daadwerkelijke implementatie van de door Spring beheerde DAO is inderdaad verborgen omdat we er niet rechtstreeks mee werken. Dit is echter een implementatie die eenvoudig genoeg is - de SimpleJpaRepository - die de semantiek van transacties definieert met behulp van annotaties.

Meer expliciet gebruikt dit een alleen-lezen @Transactional annotatie op klassenniveau, die vervolgens wordt overschreven voor de niet-alleen-lezen methoden. De rest van de transactiesemantiek is standaard, maar deze kunnen eenvoudig handmatig per methode worden overschreven.

4.1. Uitzonderingsvertaling is levend en wel

De vraag is nu - aangezien Spring Data JPA niet afhankelijk is van de oude ORM-sjablonen (JpaTemplate, HibernateTemplate) en ze zijn verwijderd sinds Spring 5 - gaan we onze PPV-uitzonderingen nog steeds laten vertalen naar Spring's DataAccessException hiërarchie?

Natuurlijk zijn we - uitzonderingsvertaling is nog steeds mogelijk door het gebruik van de @Repository annotatie op de DAO. Deze annotatie stelt een Spring Bean-postprocessor in staat om iedereen te adviseren @Repository bonen met alle PersistenceExceptionTranslator instanties die in de container zijn gevonden, en bieden uitzonderingsvertaling net als voorheen.

Laten we de vertaling van uitzonderingen verifiëren met een integratietest:

@Test (verwacht = DataIntegrityViolationException.class) openbare leegte gegevenFooHasNoName_whenInvalidEntityIsCreated_thenDataException () {service.create (nieuwe Foo ()); }

Houd daar rekening mee vertaling van uitzonderingen gebeurt via proxy's. Om ervoor te zorgen dat Spring proxy's rond de DAO-klassen kan maken, mogen deze niet worden gedeclareerd laatste.

5. Spring Data JPA Repository Configuratie

Om de Spring JPA-repository-ondersteuning te activeren, kunnen we de @EnableJpaRepositories annotatie en specificeer het pakket dat de DAO-interfaces bevat:

@EnableJpaRepositories (basePackages = "com.baeldung.spring.data.persistence.repository") openbare klasse PersistenceConfig {...}

We kunnen hetzelfde doen met een XML-configuratie:

6. Java- of XML-configuratie

In een vorig artikel hebben we al uitvoerig besproken hoe JPA in het voorjaar moet worden geconfigureerd. Spring Data maakt ook gebruik van Spring's steun voor de PPV @PersistenceContext annotatie. Het gebruikt dit om de EntityManager in de Spring-fabrieksboon die verantwoordelijk is voor het maken van de daadwerkelijke DAO-implementaties - JpaRepositoryFactoryBean.

Naast de reeds besproken configuratie, moeten we ook de Spring Data XML Config opnemen - als we XML gebruiken:

@Configuration @EnableTransactionManagement @ImportResource ("classpath *: * springDataConfig.xml") openbare klasse PersistenceJPAConfig {...}

7. Maven Afhankelijkheid

Naast de Maven-configuratie voor JPA, zoals in een vorig artikel, zullen we het spring-data-jpa afhankelijkheid:

 org.springframework.data spring-data-jpa 2.2.7.RELEASE 

8. Spring Boot gebruiken

We kunnen ook de Spring Boot Starter Data JPA-afhankelijkheid gebruiken die automatisch het Databron voor ons.

We moeten er ook voor zorgen dat de database die we willen gebruiken aanwezig is in het klassenpad. In ons voorbeeld hebben we de H2 in-memory database toegevoegd:

 org.springframework.boot spring-boot-starter-data-jpa 2.2.6.RELEASE com.h2database h2 1.4.200 

Als gevolg hiervan, alleen al door deze afhankelijkheden uit te voeren, is onze applicatie actief en kunnen we deze gebruiken voor andere databasebewerkingen.

De expliciete configuratie voor een standaard Spring-applicatie is nu opgenomen als onderdeel van de automatische configuratie van Spring Boot.

We kunnen de autoconfiguratie natuurlijk wijzigen door onze aangepaste expliciete configuratie toe te voegen.

Spring Boot biedt een gemakkelijke manier om dit te doen met behulp van eigenschappen in het application.properties het dossier:

spring.datasource.url = jdbc: h2: mem: db; DB_CLOSE_DELAY = -1 spring.datasource.username = sa spring.datasource.password = sa

In dit voorbeeld hebben we de verbindings-URL en inloggegevens gewijzigd.

9. Conclusie

Dit artikel behandelde de configuratie en implementatie van de persistentielaag met Spring 5, JPA 2 en Spring Data JPA (onderdeel van het Spring Data-overkoepelende project), waarbij zowel XML- als Java-gebaseerde configuratie werd gebruikt.

We hebben manieren besproken om meer te definiëren geavanceerde aangepaste zoekopdrachten, net zoals transactionele semantiek, en een configuratie met de nieuwe jpa naamruimte. Het uiteindelijke resultaat is een nieuwe en elegante kijk op gegevenstoegang met Spring, zonder echt implementatiewerk.

De implementatie van deze Spring Data JPA-zelfstudie is te vinden in het GitHub-project.