Programmering

Kom i gang med dvalemodus

Det er godt å forstå behovet for objekt- / relasjonskartlegging (ORM) i Java-applikasjoner, men du er sannsynligvis ivrig etter å se dvalemodus i aksjon. Vi begynner med å vise deg et enkelt eksempel som viser noe av kraften.

Som du sikkert er klar over, er det tradisjonelt at en programmeringsbok begynner med et "Hello World" -eksempel. I dette kapittelet følger vi den tradisjonen ved å introdusere Hibernate med et relativt enkelt "Hello World" -program. Men bare å skrive ut en melding til et konsollvindu vil ikke være nok til å virkelig demonstrere dvalemodus. I stedet lagrer programmet nyopprettede objekter i databasen, oppdaterer dem og utfører spørsmål for å hente dem fra databasen.

I tillegg til det kanoniske "Hello World" -eksemplet introduserer vi kjernen Hibernate API-er og gir detaljer for en grunnleggende konfigurasjon.

"Hello World" med dvalemodus

Dvalemodusapplikasjoner definerer vedvarende klasser som er "kartlagt" til databasetabeller. Eksemplet vårt "Hello World" består av en klasse og en kartleggingsfil. La oss se hvordan en enkel vedvarende klasse ser ut, hvordan kartleggingen er spesifisert, og noen av tingene vi kan gjøre med forekomster av den vedvarende klassen som bruker dvalemodus.

Målet med prøveeksemplet vårt er å lagre meldinger i en database og å hente dem for visning. Søknaden har en enkel vedvarende klasse, Beskjed, som representerer disse utskrivbare meldingene. Våre Beskjed klasse vises i oppføring 1.

Oppføring 1. Message.java: En enkel vedvarende klasse

pakke hei; offentlig klasse Melding {privat Lang id; privat strengtekst; privat melding nextMessage; privat melding () {} offentlig melding (strengtekst) {this.text = tekst; } offentlig Lang getId () {retur id; } privat ugyldig setId (lang id) {this.id = id; } offentlig streng getText () {returtekst; } public void setText (String text) {this.text = text; } offentlig melding getNextMessage () {return nextMessage; } public void setNextMessage (Message nextMessage) {this.nextMessage = nextMessage; }} 

Våre Beskjed klasse har tre attributter: identifikatorattributtet, teksten til meldingen og en referanse til en annen Beskjed. Identifikatorattributtet gir applikasjonen tilgang til databaseidentiteten - den primære nøkkelverdien - til et vedvarende objekt. Hvis to tilfeller av Beskjed har samme identifikasjonsverdi, representerer de samme rad i databasen. Vi har valgt Lang for typen identifikatorattributt, men dette er ikke et krav. Dvalemodus tillater praktisk talt alt for identifikasjonstypen, som du vil se senere.

Du har kanskje lagt merke til at alle attributtene til Beskjed klasse har metoder for tilgang til JavaBean-stil. Klassen har også en konstruktør uten parametere. De vedvarende klassene vi bruker i eksemplene våre, vil nesten alltid se ut som dette.

Forekomster av Beskjed klasse kan administreres (gjøres vedvarende) av dvalemodus, men de gjør det ikke ha å være. Siden Beskjed objektet implementerer ingen dvalespesifikke klasser eller grensesnitt, vi kan bruke det som alle andre Java-klasser:

Meldingsmelding = ny melding ("Hello World"); System.out.println (message.getText ()); 

Dette kodefragmentet gjør akkurat det vi har forventet fra "Hello World" -applikasjoner: Den skrives ut "Hei Verden" til konsollen. Det kan se ut som om vi prøver å være søte her; faktisk demonstrerer vi en viktig funksjon som skiller dvalemodus fra noen andre utholdenhetsløsninger, for eksempel EJB (Enterprise JavaBean) enhetsbønner. Vår vedvarende klasse kan brukes i hvilken som helst utførelsessammenheng - ingen spesiell container er nødvendig. Selvfølgelig kom du hit for å se dvalemodus selv, så la oss lagre en ny Beskjed til databasen:

Sessionsøkt = getSessionFactory (). OpenSession (); Transaksjon tx = session.beginTransaction (); Meldingsmelding = ny melding ("Hello World"); session.save (melding); tx.commit (); session.close (); 

Denne koden kaller dvalemodus Økt og Transaksjon grensesnitt. (Vi kommer til det getSessionFactory () ring snart.) Det resulterer i kjøring av noe som ligner på følgende SQL:

sett inn i MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) verdier (1, 'Hello World', null) 

Vent - den MESSAGE_ID kolonnen initialiseres til en merkelig verdi. Vi satte ikke inn id tilhører beskjed hvor som helst, så vi forventer at det skal være null, Ikke sant? Egentlig, den id eiendommen er spesiell: Det er en identifikasjonsegenskap—Det har en generert unik verdi. (Vi diskuterer hvordan verdien genereres senere.) Verdien tildeles til Beskjed instans av dvalemodus når lagre() er kalt.

For dette eksemplet antar vi at MELDINGER tabellen eksisterer allerede. Selvfølgelig ønsker vi at "Hello World" -programmet vårt skal skrive ut meldingen til konsollen. Nå som vi har en melding i databasen, er vi klare til å demonstrere dette. Det neste eksemplet henter alle meldinger fra databasen, i alfabetisk rekkefølge, og skriver dem ut:

Session newSession = getSessionFactory (). OpenSession (); Transaksjon newTransaction = newSession.beginTransaction (); Listemeldinger = newSession.find ("fra Melding som m rekkefølge etter m.text asc"); System.out.println (meldinger.størrelse () + "melding (er) funnet:"); for (Iterator iter = messages.iterator (); iter.hasNext ();) {Message message = (Message) iter.next (); System.out.println (message.getText ()); } newTransaction.commit (); newSession.close (); 

Den bokstavelige strengen "fra melding som m rekkefølge etter m.text asc" er en Hibernate-spørring, uttrykt i Hibernates eget objektorienterte Hibernate Query Language (HQL). Dette spørsmålet oversettes internt til følgende SQL når finne() er kalt:

velg m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID fra MESSAGES m rekkefølge etter m.MESSAGE_TEXT asc 

Kodefragmentet skrives ut:

1 melding (er) funnet: Hello World 

Hvis du aldri har brukt et ORM-verktøy som Hibernate før, forventet du sannsynligvis å se SQL-setningene et sted i koden eller metadataene. De er ikke der. All SQL genereres ved kjøretid (faktisk ved oppstart, for alle gjenbrukbare SQL-setninger).

For å la denne magien oppstå, trenger dvalemodus mer informasjon om hvordan Beskjed klassen skal gjøres vedvarende. Denne informasjonen er vanligvis gitt i en XML-kartleggingsdokument. Kartleggingsdokumentet definerer blant annet hvordan egenskaper til Beskjed klassekart til kolonner i MELDINGER bord. La oss se på kartleggingsdokumentet i Oppføring 2.

Oppføring 2. En enkel dvalemodus XML-kartlegging

Kartleggingsdokumentet forteller dvalemodus at Beskjed klassen skal holdes fast til MELDINGER tabellen, at identifikasjonsegenskapen tilordnes til en kolonne som heter MESSAGE_ID, at tekstegenskapen tilordnes til en kolonne som heter MESSAGE_TEXT, og at eiendommen navngitt neste Melding er en tilknytning til mange-til-en-mangfold som tilordnes til en kolonne som heter NESTE_MESSAGE_ID. (Ikke bekymre deg for de andre detaljene foreløpig.)

Som du kan se, er ikke XML-dokumentet vanskelig å forstå. Du kan enkelt skrive og vedlikeholde den for hånd. Uansett hvilken metode du velger, har dvalemodus nok informasjon til å generere alle SQL-setningene som trengs for å sette inn, oppdatere, slette og hente forekomster av Beskjed klasse. Du trenger ikke lenger å skrive disse SQL-setningene for hånd.

Merk
Mange Java-utviklere har klaget på "metadatahelvetet" som følger J2EE-utviklingen. Noen har foreslått en bevegelse fra XML-metadata tilbake til vanlig Java-kode. Selv om vi applauderer dette forslaget for noen problemer, representerer ORM et tilfelle der tekstbaserte metadata virkelig er nødvendig. Dvalemodus har fornuftige standarder som minimerer skriving og en moden dokumenttypedefinisjon som kan brukes til automatisk fullføring eller validering i redaktører. Du kan til og med automatisk generere metadata med forskjellige verktøy.

La oss nå endre vår første melding, og mens vi er i gang, oppretter du en ny melding tilknyttet den første, som vist i liste 3.

Oppføring 3. Oppdatere en melding

Sessionsøkt = getSessionFactory (). OpenSession (); Transaksjon tx = session.beginTransaction (); // 1 er den genererte ID-en til den første meldingen Message message = (Message) session.load (Message.class, new Long (1)); message.setText ("Hilsen Earthling"); Melding nextMessage = ny melding ("Ta meg til lederen din (vær så snill)"); message.setNextMessage (nextMessage); tx.commit (); session.close (); 

Denne koden kaller tre SQL-setninger i samme transaksjon:

velg m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID fra MESSAGES m hvor m.MESSAGE_ID = 1 sett inn i MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) verdier (2, 'Ta meg til lederen din (vær så snill)', null) oppdater MESSAGES sett MESSAGE_TEXT = 'Hilsen Earthling', NEXT_MESSAGE_ID = 2 hvor MESSAGE_ID = 1 

Legg merke til hvordan dvalemodus oppdaget endringen til tekst og neste Melding egenskapene til den første meldingen og automatisk oppdatert databasen. Vi har utnyttet en dvalemodus-funksjon som heter automatisk skittenkontroll: denne funksjonen sparer oss for å eksplisitt be dvalemodus om å oppdatere databasen når vi endrer tilstanden til et objekt i en transaksjon. På samme måte kan du se at den nye meldingen ble gjort vedvarende da en referanse ble opprettet fra den første meldingen. Denne funksjonen kalles cascading lagre: det sparer oss for å eksplisitt gjøre det nye objektet vedvarende ved å ringe lagre(), så lenge det kan nås ved en allerede vedvarende forekomst. Legg også merke til at bestillingen av SQL-setningene ikke er den samme som rekkefølgen vi setter eiendomsverdier i. Dvalemodus bruker en sofistikert algoritme for å bestemme en effektiv ordre som unngår databrudd på fremmednøkkelbegrensninger i databasen, men som fortsatt er tilstrekkelig forutsigbar for brukeren. Denne funksjonen kalles transaksjonell nedskrivning.

Hvis vi kjører "Hello World" igjen, skrives det ut:

2 meldinger funnet: Hilsen Earthling Ta meg til lederen din (vær så snill) 

Dette er så langt vi tar "Hello World" -applikasjonen. Nå som vi endelig har litt kode under beltet, tar vi et skritt tilbake og presenterer en oversikt over Hibernates viktigste API-er.

Å forstå arkitekturen

Programmeringsgrensesnittene er det første du må lære om dvalemodus for å bruke det i utholdenhetslaget i applikasjonen. Et hovedmål med API-design er å holde grensesnittene mellom programvarekomponenter så smale som mulig. I praksis er ORM API-er imidlertid ikke spesielt små. Ikke bekymre deg, skjønt; du trenger ikke å forstå alle dvalemodusgrensesnittene på en gang. Figuren nedenfor illustrerer rollene til de viktigste dvalemodusgrensesnittene i forretnings- og utholdenhetslagene.

Vi viser virksomhetslaget over utholdenhetslaget, siden virksomhetslaget fungerer som en klient av utholdenhetslaget i et tradisjonelt lagdelt program. Merk at noen enkle applikasjoner kanskje ikke skiller forretningslogikk fra persistenslogikk rent; det er greit - det forenkler bare diagrammet.

Dvalemodusgrensesnittene vist i figuren ovenfor kan omtrent klassifiseres som følger:

  • Grensesnitt som kalles av applikasjoner for å utføre grunnleggende CRUD (opprette / lese / oppdatere / slette) og spørringsoperasjoner. Disse grensesnittene er hovedavhengigheten av applikasjonsvirksomhet / kontrolllogikk i dvalemodus. De inkluderer Økt, Transaksjon, og Spørsmål.
  • Grensesnitt kalt av applikasjonsinfrastrukturkode for å konfigurere dvalemodus, viktigst av alt, Konfigurasjon klasse.
  • Ring tilbake grensesnitt som lar applikasjonen reagere på hendelser som forekommer i dvalemodus, for eksempel Interceptor, Livssyklus, og Validerbar.
  • Grensesnitt som tillater utvidelse av Hibernates kraftige kartfunksjonalitet, for eksempel Brukertype, CompositeUserType, og IdentifierGenerator. Disse grensesnittene er implementert med applikasjonsinfrastrukturkode (om nødvendig).

Hibernate bruker eksisterende Java API-er, inkludert JDBC (Java Database Connectivity), Java Transaction API (JTA) og Java Naming and Directory Interface (JNDI). JDBC gir et rudimentært nivå av abstraksjon av funksjonalitet som er felles for relasjonsdatabaser, slik at nesten alle databaser med en JDBC-driver kan støttes av dvalemodus. JNDI og JTA lar Hibernate integreres med J2EE applikasjonsservere.

I denne delen dekker vi ikke den detaljerte semantikken til Hibernate API-metoder, bare rollen til hvert av de primære grensesnittene. Du finner de fleste av disse grensesnittene i pakken net.sf. dvale. La oss ta en kort titt på hvert grensesnitt etter tur.

Kjernegrensesnittene

De fem kjernegrensesnittene brukes i omtrent alle dvalemodusapplikasjoner. Ved å bruke disse grensesnittene kan du lagre og hente vedvarende objekter og kontrollere transaksjoner.

Sessionsgrensesnitt

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