Programmering

Objekt persistens og Java

Objektets holdbarhed eller udholdenhed, er det udtryk, du ofte hører brugt i forbindelse med spørgsmålet om lagring af objekter i databaser. Persistens forventes at fungere med transaktionsintegritet, og som sådan er det underlagt strenge betingelser. (Se afsnittet Ressourcer i denne artikel for at få flere oplysninger om transaktionsbehandling.) I modsætning hertil er sprogtjenester, der tilbydes via standard sprogbiblioteker og pakker, ofte fri for transaktionsbegrænsninger.

Som vi vil se i denne artikel antyder beviser, at simpel Java-persistens sandsynligvis stammer fra selve sproget, mens sofistikeret databasefunktionalitet vil blive tilbudt af databaseleverandører.

Intet objekt er en ø

I den virkelige verden finder du sjældent et objekt, der mangler forhold til andre objekter. Objekter er komponenter i objektmodeller. Spørgsmålet om objektets holdbarhed overskrider spørgsmålet om objektmodelens holdbarhed og distribution, når vi først har observeret, at objekter er sammenkoblet i kraft af deres forhold til hinanden.

Den relationelle tilgang til datalagring har tendens til at samle data efter type. Rækker i en tabel repræsenterer det fysiske aggregat af objekter af samme type på disken. Forholdet mellem objekter er derefter repræsenteret af nøgler, der deles på tværs af mange tabeller. Selvom relationsdatabaser undertiden gennem databaseorganisation tillader, at tabeller, der sandsynligvis vil blive brugt sammen, samlokaliseres (eller grupperet) i den samme logiske partition, såsom et databasesegment, har de ingen mekanisme til at gemme objektforhold i databasen. For at konstruere en objektmodel konstrueres disse relationer derfor ud fra de eksisterende nøgler i løbetid i en proces kaldet tabel slutter sig til. Dette er den samme velkendte egenskab ved de relationsdatabaser, der kaldes data uafhængighed. Næsten alle varianter af objektdatabaser tilbyder en eller anden mekanisme til at forbedre ydeevnen for et system, der involverer komplekse objektforhold i forhold til traditionelle relationsdatabaser.

Forespørgsel eller navigering?

Ved lagring af objekter på disk står vi over for valget af samlokalisering af relaterede objekter for bedre at imødekomme navigationsadgang eller til at gemme objekter i tabellignende samlinger, der samler objekter efter type for at lette predikatbaseret adgang (forespørgsler) eller begge dele . Samlokaliseringen af ​​objekter i vedvarende lagring er et område, hvor relationelle og objektorienterede databaser er meget forskellige. Valget af forespørgselssprog er et andet område, der skal overvejes. Structured Query Language (SQL) og udvidelser af det har givet relationssystemer en predikatbaseret adgangsmekanisme. Object Query Language (OQL) er en objektvariant af SQL, standardiseret af ODMG, men understøttelse af dette sprog er i øjeblikket ringe. Polymorfe metoder tilbyder enestående elegance i konstruktionen af ​​en semantisk forespørgsel til en samling objekter. Forestil dig f.eks. En polymorf adfærd for konto hedder erInGoodStanding. Det returnerer muligvis den booleske sandhed for alle konti i god anseelse og ellers falsk. Forestil dig nu elegancen ved at stille spørgsmål til samling af konti, hvor inGoodStanding implementeres forskelligt baseret på forretningsregler for alle konti med god status. Det kan se ud som:

setOfGoodCustomers = setOfAccounts.query (account.inGoodStanding ());

Mens flere af de eksisterende objektdatabaser er i stand til at behandle en sådan forespørgselsstil i C ++ og Smalltalk, er det vanskeligt for dem at gøre det for større samlinger (f.eks. 500+ gigabyte) og mere komplekse forespørgselsudtryk. Flere af de relationelle databaseselskaber, såsom Oracle og Informix, vil snart tilbyde anden, SQL-baseret syntaks for at opnå det samme resultat.

Persistens og type

En objektorienteret sprogfans vil sige vedholdenhed og type er ortogonale egenskaber for et objekt; vedvarende og forbigående objekter af samme type kan være identiske, fordi den ene egenskab ikke skal påvirke den anden. Den alternative opfattelse hævder, at vedholdenhed er en adfærd, der kun understøttes af vedvarende objekter, og at visse adfærd muligvis kun gælder for vedvarende objekter. Den sidstnævnte tilgang kræver metoder, der instruerer vedvarende objekter om at gemme og hente sig fra vedvarende lagring, mens førstnævnte giver applikationen en problemfri visning af hele objektmodellen - ofte ved at udvide det virtuelle hukommelsessystem.

Kanonisering og sproguafhængighed

Objekter af samme type på et sprog skal lagres i vedvarende lagring med samme layout, uanset rækkefølgen, hvor deres grænseflader vises. Processerne til at omdanne et objektlayout til dette almindelige format kaldes samlet kanonisering af objektrepræsentation. På kompilerede sprog med statisk skrivning (ikke Java) skal objekter skrevet på det samme sprog, men kompileret under forskellige systemer, repræsenteres identisk i vedvarende lagring.

En udvidelse af kanonisering adresserer sproguafhængig objektrepræsentation. Hvis objekter kan repræsenteres på en sproguafhængig måde, vil det være muligt for forskellige repræsentationer af det samme objekt at dele det samme vedvarende lager.

En mekanisme til at udføre denne opgave er at indføre et yderligere niveau af indirektion gennem et interface definition sprog (IDL). Objektdatabasegrænseflader kan laves gennem IDL og de tilsvarende datastrukturer. Ulempen ved IDL-stilbindinger er to gange: For det første kræver det ekstra niveau af indirektion altid et yderligere niveau for oversættelse, hvilket påvirker systemets samlede ydeevne; for det andet begrænser det brugen af ​​databasetjenester, der er unikke for bestemte leverandører, og som kan være værdifulde for applikationsudviklere.

En lignende mekanisme er at understøtte objekttjenester gennem en udvidelse af SQL. Relationelle databaseleverandører og mindre objekt- / relationsleverandører er tilhængere af denne tilgang; Det er dog stadig uvist, hvor succesrige disse virksomheder vil være med at udforme rammerne for objektlagring.

Men spørgsmålet er stadig: Er objektets vedholdenhed en del af objektets adfærd, eller er det en ekstern tjeneste, der tilbydes objekter via separate grænseflader? Hvad med samlinger af objekter og metoder til forespørgsel? Relationelle, udvidede relationelle og objekt / relationelle tilgange har tendens til at tale for en adskillelse mellem sprog, mens objektdatabaser - og selve Java-sproget - ser vedholdenhed som iboende for sproget.

Native Java-persistens via serialisering

Objektserialisering er den Java-sprogspecifikke mekanisme til lagring og hentning af Java-objekter og primitiver til streams. Det er værd at bemærke, at selvom kommercielle tredjepartsbiblioteker til serialisering af C ++ - objekter har eksisteret i nogen tid, har C ++ aldrig tilbudt en indbygget mekanisme til objektserialisering. Sådan bruges Java's serialisering:

// Skriv "foo" til en stream (for eksempel en fil)

// Trin 1. Opret en outputstrøm

// det vil sige oprette spand for at modtage byte

FileOutputStream out = ny FileOutputStream ("fooFile");

// Trin 2. Opret ObjectOutputStream

// det vil sige, opret en slange og læg hovedet i spanden

ObjectOutputStream os = ny ObjectOutputStream (ud)

// Trin 3. Skriv en streng og et objekt til strømmen

// det vil sige, lad strømmen strømme ind i spanden

os.writeObject ("foo");

os.writeObject (ny Foo ());

// Trin 4. Skyl dataene til deres destination

os.flush ();

Det Skrivobjekt metoden serialiserer foo og dens transitive lukning - det vil sige alle objekter, der kan henvises til fra foo i grafen. Inden for streamen findes der kun en kopi af det serielle objekt. Andre referencer til objekterne gemmes som objekthåndtag for at spare plads og undgå cirkulære referencer. Det serieliserede objekt starter med klassen efterfulgt af felterne for hver klasse i arvehierarkiet.

// Læsning af et objekt fra en stream

// Trin 1. Opret en inputstrøm

FileInputStream in = ny FileInputStream ("fooFile");

// Trin 2. Opret en objektinputstrøm

ObjectInputStream ins = ny ObjectInputStream (in);

// Trin 3. Fik at vide, hvad du læser

String fooString = (String) ins.readObject ();

Foo foo = (Foo) s.readObject ();

Objektserialisering og sikkerhed

Som standard skriver og læser serialisering ikke-statiske og ikke-forbigående felter fra strømmen. Denne egenskab kan bruges som en sikkerhedsmekanisme ved at erklære felter, der muligvis ikke serieliseres som private forbigående. Hvis en klasse overhovedet muligvis ikke serieliseres, skrivObject og readObject metoder skal implementeres for at kaste NoAccessException.

Persistens med transaktionsintegritet: Introduktion til JDBC

Modelleret efter X / Open's SQL CLI (Client Level Interface) og Microsofts ODBC-abstraktioner har Java-databaseforbindelse (JDBC) til formål at tilvejebringe en databaseforbindelsesmekanisme, der er uafhængig af det underliggende databasestyringssystem (DBMS). For at blive JDBC-kompatibel drivere skal understøtte mindst ANSI SQL-2 API på indgangsniveau, som giver tredjepartsværktøjsleverandører og applikationer tilstrækkelig fleksibilitet til databaseadgang.

JDBC er designet til at være i overensstemmelse med resten af ​​Java-systemet. Leverandører opfordres til at skrive en API, der er stærkere skrevet end ODBC, hvilket giver større statisk typekontrol ved kompileringstidspunktet.

Her er en beskrivelse af de vigtigste JDBC-grænseflader:

  • java.sql.Driver.Manager håndterer indlæsning af drivere og yder support til nye databaseforbindelser.

  • java.sql.Tilslutning repræsenterer en forbindelse til en bestemt database.

  • java.sql.Statement fungerer som en container til at udføre en SQL-sætning på en given forbindelse.

  • java.sql.ResultSet styrer adgang til resultatsættet.

Du kan implementere en JDBC-driver på flere måder. Det enkleste ville være at bygge føreren som en bro til ODBC. Denne tilgang er bedst egnet til værktøjer og applikationer, der ikke kræver høj ydeevne. Et mere udvideligt design vil introducere et ekstra niveau af indirektion til DBMS-serveren ved at tilvejebringe en JDBC-netværksdriver, der får adgang til DBMS-serveren gennem en offentliggjort protokol. Den mest effektive driver ville dog direkte få adgang til DBMS proprietære API.

Objektdatabaser og Java-persistens

En række igangværende projekter i branchen tilbyder Java-persistens på objektniveau. Imidlertid er Object Designs PSE (Persistent Storage Engine) og PSE Pro den eneste fuldt Java-baserede, objektorienterede databasepakke til rådighed (i det mindste jeg er opmærksom på). Se afsnittet Ressourcer for at få flere oplysninger om PSE og PSE Pro.

Java-udvikling har ført til en afvigelse fra det traditionelle udviklingsparadigme for softwareleverandører, især inden for tidslinjen for udviklingsprocessen. For eksempel er PSE og PSE Pro udviklet i et heterogent miljø. Og fordi der ikke er et sammenkædningstrin i udviklingsprocessen, har udviklere været i stand til at oprette forskellige funktionelle komponenter uafhængigt af hinanden, hvilket resulterer i bedre, mere pålidelig objektorienteret kode.

PSE Pro har evnen til at gendanne en beskadiget database fra en afbrudt transaktion forårsaget af systemfejl. De klasser, der er ansvarlige for denne tilføjede funktionalitet, er ikke til stede i PSE-udgivelsen. Der er ingen andre forskelle mellem de to produkter. Disse produkter er det, vi kalder "dribbleware" - softwareudgivelser, der forbedrer deres funktionalitet ved at tilslutte nye komponenter. I en ikke så fjern fremtid ville konceptet med at købe stor, monolitisk software blive fortid. Det nye forretningsmiljø i cyberspace sammen med Java-computing gør det muligt for brugerne kun at købe de dele af objektmodellen (objektgraf), de har brug for, hvilket resulterer i mere kompakte slutprodukter.

PSE fungerer ved efterbehandling og kommentering af klassefiler, efter at de er oprettet af udvikleren. Fra PSE's synspunkt er klasser i en objektgraf enten vedvarende eller vedvarende opmærksomme. Vedvarende klasser kan fastholde sig selv, mens vedvarende klasser kan fungere på vedvarende objekter. Denne skelnen er nødvendig, fordi vedholdenhed muligvis ikke er en ønsket opførsel for visse klasser. Klassefilen efterbehandler foretager følgende ændringer til klasser: