Introduktion til Apache Cayenne ORM

1. Oversigt

Apache Cayenne er et open source-bibliotek, distribueret under Apache-licensen, der leverer funktioner som et modelleringsværktøj, objektrelationskortlægning aka ORM til lokal persistensoperation og fjernbetjeningstjenester.

I de følgende afsnit vil vi se, hvordan man interagerer med en MySQL-database ved hjælp af Apache Cayenne ORM.

2. Maven-afhængigheder

For at starte er vi bare nødt til at tilføje følgende afhængigheder for at få Apache Cayenne og MySQL-stik JDBC-driveren sammen for at få adgang til vores intro_cayenne database:

 org.apache.cayenne cayenne-server 4.0.M5 mysql mysql-connector-java 5.1.44 runtime 

Lad os konfigurere Cayenne modeler-plugin, der skal bruges til at designe eller indstille vores kortlægningsfil, der fungerer som en bro mellem databaseskemaet og Java-objektet:

 org.apache.cayenne.plugins maven-cayenne-modeler-plugin 4.0.M5 

I stedet for at opbygge XML-kortlægningsfil manuelt (lavet sjældent) anbefales det at bruge modeleren, som er et ret avanceret værktøj, der følger med Cayenne-distributionen.

Det kan downloades fra dette arkiv afhængigt af dit operativsystem eller brug bare den platform-version (JAR), der er inkluderet som et Maven-plugin deroppe.

Maven Central-arkivet er vært for de nyeste versioner af Apache Cayenne, hans modellerer og MySQL Connector.

Lad os derefter bygge vores projekt med mvn installere og start modeler GUI med kommandoen mvn cayenne-modeler: kør at få som output dette skærmbillede:

3. Opsætning

For at få Apache Cayenne til at slå den korrekte lokale database op, skal vi bare udfylde hans konfigurationsfil med den rigtige driver, URL og en bruger i filen cayenne-project.xml placeret i ressourcer vejviser:

Her kan vi se det:

  • Den lokale database er navngivet intro_cayenne
  • Hvis den endnu ikke er oprettet, vil Cayenne gøre det for os
  • Vi opretter forbindelse ved hjælp af brugernavnet rod og adgangskode rod (skift det i henhold til de brugere, der er registreret i dit databasestyringssystem)

Internt er det XMLPoolingDataSourceFactory ansvarlig for at indlæse JDBC - forbindelsesoplysninger fra en XML - ressource, der er knyttet til DataNodeDescriptor.

Vær opmærksom på, at disse parametre er relative til databasestyringssystemet og en JDBC-driver, fordi dette bibliotek kan understøtte mange forskellige databaser.

Hver af dem har en adapter tilgængelig i denne detaljerede liste. Bemærk, at den fulde dokumentation til version 4.0 endnu ikke er tilgængelig, så vi henviser til den tidligere version her.

4. Kortlægning og databasedesign

4.1. Modellering

Lad os nu klikke på “Åbent projekt”, naviger til projektets ressourcemappe og vælg filen cayenne-project.xml, modellereren viser dette:

Her, vi har valget om enten at oprette vores kortlægningsstruktur fra en eksisterende databaseeller for at fortsætte manuelt. Denne artikel håndterer den, der bruger modellereren og den eksisterende database til at komme ind i Cayenne og hurtigt vide, hvordan den fungerer.

Lad os se på vores intro_cayenne database, der har en en-til-mange forhold på tværs af to tabeller, da en forfatter kan offentliggøre eller eje mange artikler:

  • forfatter: id (PK) og navn
  • artikel: id (PK), titel, indholdog author_id (FK)

Lad os nu gå til “Værktøjer> Reengineer Database Schema“, Og vi får alle vores kortlægningskonfigurationer udfyldt automatisk. På hurtigskærmen skal du blot udfylde den tilgængelige datakildekonfiguration deroppe i cayenne-project.xml fil og tryk på Fortsæt:

På den næste skærm skal vi kontrollere "Brug Java primitive typer" som følger:

Vi skal også sørge for at sætte com.baeldung.apachecayenne.persistent som Java-pakke og gem den; Vi ser, at XML-konfigurationsfilen er opdateret til dens standardpakke egenskab, der matcher Java-pakken:

I hver Objekt vi skal specificere pakken til underklasser som vist i det følgende billede og klikke på "Gemme" ikon igen:

Nu på "Værktøjer> Generer klasser" menu, vælg “Standard vedvarende genstande”Som typen; og på “Klasser” fanen tjek alle klasser og tryk "frembringe".

Lad os gå tilbage til kildekoden for at se, at vores vedvarende objekter er genereret med succes og taler om _Article.java og _Author.java.

Bemærk, at alle disse konfigurationer er gemt i filen datamap.map.xml også placeret i ressourcer folder.

4.2. Kortlægningsstruktur

Den genererede XML-kortfil, der vises i ressourcemappen, bruger nogle unikke tags i forhold til Apache Cayenne:

  • DataNode () - databasemodellen, dens indhold alle nødvendige oplysninger for at få forbindelse til en database (databasens navn, driveren og brugeroplysningerne)
  • DataMap () - det er en beholder med vedvarende enheder med deres forhold
  • DbAttribute () - repræsenterer en kolonne i en databasetabel
  • DbEntity () - modellen til en enkelt databasetabel eller -visning kan have DbAttributter og relationer
  • ObjEntity () - modellen til en enkelt vedvarende java-klasse lavet af ObjAttributter, der svarer til enhedsklasseegenskaber og ObjRelationships, der er egenskaber, der har en type af en anden enhed
  • Kan integreres () - modellen til en Java-klasse, der fungerer som en egenskab for en ObjEntity, men svarer til flere kolonner i databasen
  • Procedure() - at registrere lagret procedure i databasen
  • Forespørgsel() - modellen til en forespørgsel, der bruges til at kortlægge forespørgslen i konfigurationsfilen uden at glemme, at vi også kan gøre det i koden

Her er de fulde detaljer.

5. Cayenne API

Det eneste tilbageværende trin er at bruge Cayenne API til at udføre vores databasefunktioner ved hjælp af genererede klasser, vel vidende at underklassificering af vores vedvarende klasser kun er en bedste praksis, der bruges til at tilpasse modellen senere.

5.1. Oprettelse af et objekt

Her gemmer vi bare en Forfatter gør indsigelse og kontroller senere, at der kun er én registrering af denne type i databasen:

@Test offentlig ugyldig nårInsert_thenWeGetOneRecordInTheDatabase () {Author author = context.newObject (Author.class); author.setName ("Paul"); context.commitChanges (); lange poster = ObjectSelect.dataRowQuery (Author.class) .selectCount (kontekst); assertEquals (1, poster); }

5.2. Læsning af et objekt

Efter at have gemt en Forfatter, vi vælger det bare blandt andre via en simpel forespørgsel fra en bestemt ejendom:

@Test offentligt ugyldigt nårInsert_andQueryByFirstName_thenWeGetTheAuthor () {Author author = context.newObject (Author.class); author.setName ("Paul"); context.commitChanges (); Forfatter expectAuthor = ObjectSelect.query (Author.class) .where (Author.NAME.eq ("Paul")) .selectOne (kontekst); assertEquals ("Paul", expectAuthor.getName ()); }

5.3. Henter alle poster i en klasse

Vi gemmer to forfattere og henter en samling forfatterobjekter for at kontrollere, at der netop er disse to gemte:

@Test offentlig ugyldig nårInsert_andQueryAll_thenWeGetTwoAuthors () {Author firstAuthor = context.newObject (Author.class); firstAuthor.setName ("Paul"); Forfatter secondAuthor = context.newObject (Author.class); secondAuthor.setName ("Ludovic"); context.commitChanges (); Listeforfattere = ObjectSelect .query (Author.class) .select (context); assertEquals (2, author.size ()); }

5.4. Opdatering af et objekt

Opdateringsprocessen er også let, men vi skal først have det ønskede objekt, før vi ændrer dets egenskaber og anvender det i databasen:

@Test offentlig ugyldig nårUpdating_thenWeGetAnUpatedeAuthor () {Author author = context.newObject (Author.class); author.setName ("Paul"); context.commitChanges (); Forfatter expectAuthor = ObjectSelect.query (Author.class) .where (Author.NAME.eq ("Paul")) .selectOne (kontekst); expectAuthor.setName ("Garcia"); context.commitChanges (); assertEquals (author.getName (), expectAuthor.getName ()); }

5.5. Vedhæftning af et objekt

Vi kan tildele en artikel til en forfatter:

@Test offentlig ugyldig nårAttachingToArticle_thenTheRelationIsMade () {Author author = context.newObject (Author.class); author.setName ("Paul"); Artikelartikel = context.newObject (Article.class); article.setTitle ("Mit indlægstitel"); article.setContent ("Indholdet"); article.setAuthor (forfatter); context.commitChanges (); Forfatter expectAuthor = ObjectSelect.query (Author.class). Hvor (Author.NAME.eq ("Smith")) .selectOne (kontekst); Article expectedArticle = (expectAuthor.getArticles ()). Get (0); assertEquals (article.getTitle (), expectArticle.getTitle ()); }

5.6. Sletning af et objekt

Sletningen af ​​et gemt objekt fjerner det helt fra databasen, derefter vil vi se nul som resultatet af forespørgslen:

@Test offentlig ugyldig nårDeleting_thenWeLostHisDetails () {Author author = context.newObject (Author.class); author.setName ("Paul"); context.commitChanges (); Forfatter gemtAuthor = ObjectSelect.query (Author.class). Hvor (Author.NAME.eq ("Paul")) .selectOne (kontekst); hvis (savedAuthor! = null) {context.deleteObjects (forfatter); context.commitChanges (); } Forfatter expectAuthor = ObjectSelect.query (Author.class). Hvor (Author.NAME.eq ("Paul")) .selectOne (kontekst); assertNull (forventet forfatter); }

5.7. Slet alle poster i en klasse

Det er også muligt at slippe alle poster i en tabel ved hjælp afSQLTemplate, her gør vi dette efter hver testmetode for altid at have en ugyldig database, før hver test startes:

@Efter offentlig ugyldighed deleteAllRecords () {SQLTemplate deleteArticles = ny SQLTemplate (Article.class, "delete from article"); SQLTemplate deleteAuthors = ny SQLTemplate (Author.class, "slet fra forfatter"); context.performGenericQuery (deleteArticles); context.performGenericQuery (deleteAuthors); }

6. Konklusion

I denne vejledning fokuserede vi på at bruge Apache Cayenne ORM til let at demonstrere, hvordan man udfører CRUD-operationer med en en-til-mange forhold.

Som altid kan kildekoden til denne artikel findes på GitHub.


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