Introduktion til Morphia - Java ODM til MongoDB

1. Oversigt

I denne vejledning forstår vi, hvordan man bruger Morphia, en Object Document Mapper (ODM) til MongoDB i Java.

I processen forstår vi også, hvad der er en ODM, og hvordan det letter arbejdet med MongoDB.

2. Hvad er en ODM?

For de uindviede i dette område, MongoDB er en dokumentorienteret database bygget til at distribueres af naturen. Dokumentorienterede databaser administrerer i enkle vendinger dokumenter, som ikke er andet end en skemafri måde at organisere semistrukturerede data på. De falder ind under en bredere og løst defineret paraply af NoSQL-databaser, opkaldt efter deres tilsyneladende afgang fra den traditionelle organisering af SQL-databaser.

MongoDB leverer drivere til næsten alle populære programmeringssprog som Java. Disse drivere tilbyder et abstraktionslag til at arbejde med MongoDB, så vi ikke arbejder direkte med Wire Protocol. Tænk på dette, da Oracle leverer en implementering af JDBC-driveren til deres relationsdatabase.

Men hvis vi husker vores dage med at arbejde med JDBC direkte, kan vi forstå, hvordan rodet det kan blive - især i et objektorienteret paradigme. Heldigvis har vi ORM-rammer (Object Relational Mapping) som Hibernate til vores redning. Det er ikke meget anderledes for MongoDB.

Selvom vi helt sikkert kan arbejde med driveren på lavt niveau, kræver det meget mere kedelplade for at udføre opgaven. Her har vi det et lignende koncept som ORM kaldet Object Document Mapper (ODM). Morphia fylder nøjagtigt pladsen til Java-programmeringssproget og arbejder oven på Java-driveren til MongoDB.

3. Opsætning af afhængigheder

Vi har set nok teori til at få os ind i en kode. For vores eksempler modellerer vi et bibliotek med bøger og ser, hvordan vi kan administrere det i MongoDB ved hjælp af Morphia.

Men inden vi begynder, skal vi konfigurere nogle af afhængighederne.

3.1. MongoDB

Vi skal have en kørende instans af MongoDB at arbejde med. Der er flere måder at få dette på, og den enkleste er at downloade og installere community-udgaven på vores lokale maskine.

Vi skal lade alle standardkonfigurationer være som de er, inklusive den port, som MongoDB kører på.

3.2. Morphia

Vi kan downloade de forudbyggede JAR'er til Morphia fra Maven Central og bruge dem i vores Java-projekt.

Den enkleste måde er dog at bruge et afhængighedsstyringsværktøj som Maven:

 dev.morphia.morphia core 1.5.3 

4. Hvordan oprettes forbindelse ved hjælp af Morphia?

Nu hvor vi har MongoDB installeret og kørt og har opsat Morphia i vores Java-projekt, er vi klar til at oprette forbindelse til MongoDB ved hjælp af Morphia.

Lad os se, hvordan vi kan opnå det:

Morphia morphia = ny Morphia (); morphia.mapPackage ("com.baeldung.morphia"); Datastore datastore = morphia.createDatastore (ny MongoClient (), "bibliotek"); datastore.ensureIndexes ();

Det er stort set det! Lad os forstå dette bedre. Vi har brug for to ting for at vores kortlægningsoperationer skal fungere:

  1. En kortlægger: Dette er ansvarlig for kortlægning af vores Java POJO'er til MongoDB Collections. I vores kodestykke ovenfor, Morphia er den klasse, der er ansvarlig for det. Bemærk, hvordan vi konfigurerer pakken, hvor den skal se efter vores POJO'er.
  2. En forbindelse: Dette er forbindelsen til en MongoDB-database, som kortlæggeren kan udføre forskellige operationer på. Klassen Datalager tager som parameter en forekomst af MongoClient (fra Java MongoDB-driveren) og navnet på MongoDB-databasen, returnere en aktiv forbindelse til at arbejde med.

Så vi er alle klar til at bruge dette Datalager og arbejde med vores enheder.

5. Hvordan arbejder man med enheder?

Før vi kan bruge vores friskmynte Datalager, er vi nødt til at definere nogle domæneenheder at arbejde med.

5.1. Enkel enhed

Lad os begynde med at definere en simpel Bestil enhed med nogle attributter:

@Entity ("Bøger") offentlig klasse Bog {@Id privat streng isbn; privat streng titel; privat strengforfatter; @Property ("pris") private dobbeltomkostninger; // konstruktører, getters, settere og hashCode, lig, toString implementeringer}

Der er et par interessante ting at bemærke her:

  • Læg mærke til kommentaren @Enhed der kvalificerer denne POJO til ODM-kortlægning af Morphia
  • Morphia kortlægger som standard en enhed til en samling i MongoDB med navnet på sin klasse, men vi kan eksplicit tilsidesætte dette (som vi har gjort for enheden Bestil her)
  • Morphia kortlægger som standard variablerne i en enhed til nøglerne i en MongoDB-samling med navnet på variablen, men igen kan vi tilsidesætte dette (som vi har gjort for variablen koste her)
  • Endelig skal vi markere en variabel i enheden for at fungere som den primære nøgle ved kommentaren @Id (som om vi bruger ISBN til vores bog her)

5.2. Enheder med forhold

I den virkelige verden er enheder imidlertid næppe så enkle, som de ser ud og har komplekse forhold til hinanden. For eksempel vores enkle enhed Bestil kan have en Forlægger og kan henvise til andre ledsagende bøger. Hvordan modellerer vi dem?

MongoDB tilbyder to mekanismer til at opbygge relationer - Henvisning og indlejring. Som navnet antyder, under henvisning gemmer MongoDB relaterede data som et separat dokument i den samme eller en anden samling og refererer bare til det ved hjælp af dets id.

Tværtimod, med indlejring gemmer MongoDB eller rettere hellere indlejringen af ​​forholdet i selve det overordnede dokument.

Lad os se, hvordan vi kan bruge dem. Lad os begynde med at integrere Forlægger i vores Bestil:

@Embedded privat udgiver;

Enkelt nok. Lad os nu gå videre og tilføje referencer til andre bøger:

@Reference privat liste companionBooks;

Det er det - Morphia giver bekvemme kommentarer til modelforhold som understøttet af MongoDB. Valget af henvisning til indlejring skal imidlertid trække på datamodelens kompleksitet, redundans og konsistens blandt andre overvejelser.

Øvelsen svarer til normalisering i relationelle databaser.

Nu er vi klar til at udføre nogle operationer Bestil ved brug af Datalager.

6. Nogle grundlæggende funktioner

Lad os se, hvordan vi arbejder med nogle af de grundlæggende operationer ved hjælp af Morphia.

6.1. Gemme

Lad os begynde med den enkleste af operationerne og oprette en forekomst af Bestil i vores MongoDB-database bibliotek:

Publisher publisher = new Publisher (new ObjectId (), "Awsome Publisher"); Bogbog = ny bog ("9781565927186", "Learning Java", "Tom Kirkman", 3,95, udgiver); Book companionBook = ny bog ("9789332575103", "Java Performance Companion", "Tom Kirkman", 1,95, udgiver); book.addCompanionBooks (følgebog); datastore.save (companionBook); datastore.save (bog);

Dette er nok til at lade Morphia oprette en samling i vores MongoDB-database, hvis den ikke findes, og udføre en upsert-operation.

6.2. Forespørgsel

Lad os se, om vi er i stand til at forespørge om den bog, vi lige har oprettet i MongoDB:

Listebøger = datastore.createQuery (Book.class) .field ("title") .contains ("Learning Java") .find () .toList (); assertEquals (1, books.size ()); assertEquals (bog, books.get (0));

Forespørgsel på et dokument i Morphia begynder med at oprette en forespørgsel ved hjælp af Datalager og derefter erklærende tilføje filtre til glæde for dem, der er forelsket i funktionel programmering!

Morphia understøtter langt mere kompleks forespørgselskonstruktion med filtre og operatorer. Desuden tillader Morphia at begrænse, springe over og ordne resultater i forespørgslen.

Hvad mere er, Morphia giver os mulighed for at bruge rå forespørgsler skrevet med Java-driveren til MongoDB for mere kontrol, hvis det er nødvendigt.

6.3. Opdatering

Selvom en gemningsoperation kan håndtere opdateringer, hvis den primære nøgle matcher, giver Morphia måder til selektivt at opdatere dokumenter:

Query query = datastore.createQuery (Book.class) .field ("title") .contains ("Learning Java"); UpdateOperations opdateringer = datastore.createUpdateOperations (Book.class) .inc ("pris", 1); datastore.update (forespørgsel, opdateringer); Listebøger = datastore.createQuery (Book.class) .field ("title") .contains ("Learning Java") .find () .toList (); assertEquals (4,95, books.get (0) .getCost ());

Her bygger vi en forespørgsel og en opdateringshandling for at hæve prisen for alle bøger, der returneres af forespørgslen med en.

6.4. Slet

Endelig skal det, der er oprettet, slettes! Igen med Morphia er det ret intuitivt:

Query query = datastore.createQuery (Book.class) .field ("title") .contains ("Learning Java"); datastore.delete (forespørgsel); Listebøger = datastore.createQuery (Book.class) .field ("title") .contains ("Learning Java") .find () .toList (); assertEquals (0, books.size ());

Vi opretter forespørgslen ganske ens som før og kører sletteoperationen på Datalager.

7. Avanceret brug

MongoDB har nogle avancerede operationer som Aggregation, Indexing og mange andre. Selvom det ikke er muligt at udføre alt dette ved hjælp af Morphia, er det bestemt muligt at opnå noget af det. For andre bliver vi desværre nødt til at falde tilbage til Java-driveren til MongoDB.

Lad os fokusere på nogle af disse avancerede operationer, som vi kan udføre gennem Morphia.

7.1. Aggregering

Aggregering i MongoDB giver os mulighed for at definere en række operationer i en rørledning, der kan fungere på et sæt dokumenter og producere samlet output.

Morphia har en API til at understøtte en sådan aggregeringspipeline.

Lad os antage, at vi ønsker at samle vores biblioteksdata på en sådan måde, at vi har alle bøgerne grupperet af deres forfatter:

Iterator iterator = datastore.createAggregation (Book.class) .group ("author", grouping ("books", push ("title"))). Out (Author.class);

Så hvordan fungerer dette? Vi begynder med at oprette en aggregeringsrørledning ved hjælp af den samme gamle Datalager. Vi er nødt til at give den enhed, som vi ønsker at udføre aggregeringsoperationer på, for eksempel Bestil her.

Dernæst vil vi gruppere dokumenter efter "forfatter" og samle deres "titel" under en nøgle kaldet "bøger". Endelig arbejder vi med en ODM her. Så vi er nødt til at definere en enhed til at indsamle vores samlede data - i vores tilfælde er det Forfatter.

Selvfølgelig skal vi definere en kaldet enhed Forfatter med en variabel kaldet bøger:

@Entity public class Forfatter {@Id privat strengnavn; private listebøger; // andre nødvendige getters og setters}

Dette ridser selvfølgelig bare overfladen af ​​en meget kraftig konstruktion leveret af MongoDB og kan udforskes yderligere for detaljer.

7.2. Fremskrivning

Projektion i MongoDB tillader os at vælg kun de felter, vi vil hente fra dokumenter i vores forespørgsler. Hvis dokumentstrukturen er kompleks og tung, kan dette være virkelig nyttigt, når vi kun har brug for et par felter.

Lad os antage, at vi kun behøver at hente bøger med deres titel i vores forespørgsel:

Listebøger = datastore.createQuery (Book.class) .field ("title") .contains ("Learning Java") .project ("title", true) .find () .toList (); assertEquals ("Learning Java", books.get (0) .getTitle ()); assertNull (books.get (0) .getAuthor ());

Her, som vi kan se, får vi kun titlen tilbage i vores resultat og ikke forfatteren og andre felter. Vi skal dog være forsigtige med at bruge den projicerede output til at spare tilbage til MongoDB. Dette kan resultere i datatab!

7.3. Indeksering

Indekser spiller en meget vigtig rolle i optimering af forespørgsler med databaser - såvel relationelle som mange ikke-relationelle.

MongoDB definerer indekser på niveauet for samlingen med et unikt indeks oprettet på den primære nøgle som standard. Desuden tillader MongoDB at der oprettes indekser på ethvert felt eller underfelt i et dokument. Vi skal vælge at oprette et indeks på en nøgle afhængigt af den forespørgsel, vi ønsker at oprette.

For eksempel ønsker vi i vores eksempel at oprette et indeks på feltet "titel" på Bestil som vi ofte ender med at spørge om det:

@Indexes ({@Index (fields = @Field ("title"), options = @IndexOptions (name = "book_title"))}) public class Book {// ... @Property private String title; // ...}

Naturligvis kan vi videregive yderligere indekseringsindstillinger for at skræddersy nuancerne i det indeks, der bliver oprettet. Bemærk, at feltet skal kommenteres af @Ejendom skal bruges i et indeks.

Desuden har Morphia bortset fra klasseniveauindekset en kommentar til også at definere et feltniveauindeks.

7.4. Validering af skema

Vi har en mulighed for at give datavalideringsregler for en samling, som MongoDB kan bruge, mens de udfører en opdaterings- eller indsættelseshandling. Morphia understøtter dette gennem deres API'er.

Lad os sige, at vi ikke ønsker at indsætte en bog uden en gyldig pris. Vi kan udnytte skemavalidering for at opnå dette:

@Validation ("{price: {$ gt: 0}}") public class Book {// ... @Property ("price") private dobbeltomkostninger; // ...}

Der er et rigt sæt valideringer leveret af MongoDB, der kan bruges her.

8. Alternative MongoDB ODM'er

Morphia er ikke den eneste tilgængelige MongoDB ODM til Java. Der er flere andre, som vi kan overveje at bruge i vores applikationer. En diskussion om sammenligning med Morphia er ikke mulig her, men det er altid nyttigt at kende vores muligheder:

  • Spring Data: Tilvejebringer en fjederbaseret programmeringsmodel til arbejde med MongoDB
  • MongoJack: Giver direkte kortlægning fra JSON til MongoDB-objekter

Dette er ikke en komplet liste over MongoDB ODM'er til Java, men der er nogle interessante alternativer tilgængelige!

9. Konklusion

I denne artikel forstod vi de grundlæggende detaljer i MongoDB og brugen af ​​en ODM til at oprette forbindelse og operere på MongoDB fra et programmeringssprog som Java. Vi udforskede yderligere Morphia som en MongoDB ODM til Java og de forskellige muligheder, den har.

Som altid kan koden findes på GitHub.