Object-Relational Mapping

Relaterede dokumenter
Database for udviklere. Jan Lund Madsen PBS10107

Hvorfor skal vi bruge objekt orienteret databaser?

Tietgenskolen - Nørrehus. Data warehouse. Database for udviklere. Thor Harloff Lynggaard DM08125

Databasesystemer. Databaser, efterår Troels Andreasen. Efterår 2002

Casper Fabricius ActiveRecord. O/RM i Ruby on Rails

Arkitektur principper og design mønstre til realisering af enterprise applikationer baseret på rige domænemodeller (og.net)

Data Warehouse Knowledge is Power - Sir Francis Bacon -

Studieordning del

Procesbeskrivelse - Webprogrammering

Datatekniker med programmering som speciale

Side 1. Databaser og SQL. Dagens gang. Databasebegreber. Introduktion til SQL Kap 1-5

EA3 eller EA Cube rammeværktøjet fremstilles visuelt som en 3-dimensionel terning:

Hassansalem.dk/delpin User: admin Pass: admin BACKEND

Database "opbygning"

Listen over reserverede ord er meget lang, men de væsentligste vil jeg beskrive her i denne artikel:

Udfordringer og problemstillinger. En liste over de udfordringer og problemstillinger, der er ved Java og JEE udvikling

Version Dato Beskrivelse /11/2012 Initial version /03/2013 Tilføjet eksempel med Template Agent, generelt udvidet dokumentet.

Dygtig.NET / C# udvikler med stor erfaring fra både offentlige organisationer og private virksomheder.

Datatekniker med programmering som speciale

Sammenligning af Objekt-orienteret databaser og Relationelle databaser.

Der er forsøgt skrevet en lille notits hver gang der er lavet noget, dog kan der være nogle ting som ikke er blevet kommenteret.

Indholdsfortegnelse. Systembeskrivelse kapitel 8 Administrationsdatabase

Programmering 19/ ROSKILDE TEKNISKE GYMNASIUM. Projektbeskrivelse. Programmering. Rasmus Kibsgaard Riehn-Kristensen

Arkitektur for begyndere

PHP kode til hjemmeside menu.

Udvikling af DOTNET applikationer til MicroStation i C#

DATABASE - MIN MUSIKSAMLING

Videregående Programmering for Diplom-E Noter

Specialiseringen Rapport Lavede Af Rasmus R. Sørensen Side 1 af 6

Skriftlig opgave. Designtanker i database-nære systemer

2. Systemarkitektur... 2

Software Projekt NoSQL vs RMDB

Det Nye Testamente lyd-app. v. Stefan Lykkehøj Lund

Curriculum Vitae. Type År Sidst Niveau Type År Sidst Niveau

STS Designdokument. STS Designdokument

Web CMS kontra Collaboration

har jeg hentet nedenstående anmeldelse af et godt program til

Notat ang. visning af dagsordener og referater på hjemmesiden ved skift til SBSYS esdh system.

Hvad er Objekter - Programmering

Undervisningsbeskrivelse

Database optimering - Indeks

Opret ODBC datakilde Vejledning

Abstrakte datatyper C#-version

Internet Information Services (IIS)

PHP Quick Teknisk Ordbog

Optimering af fraværsregistrering

SIMS integration med Microsoft Active Directory, er implementeret, via en mellemdatabase.

EasyIQ Opdatering > 5.4.0

SYSTEMDOKUMENTATION AF POC

APEX i Praksis Martin B. Nielsen. Navn. MBNDATA Emne

Ide med Diff. Mål. Tidsplan. 1.uge: 2.uge:

EG Data Inform. Byggebasen. WCF og webservices. Jens Karsø

SWC eksamens-spørgsmål. Oversigt

ADIS, WS og Meta Service

Identifikation af planer der ikke findes i PlansystemDK vha. datasættet... 9

Roskilde Tekniske Gymnasium. Eksamensprojekt. Programmering C niveau

Opsætning af udviklerversion af Microsofts open source XDS.b fra Codeplex Projekt: Net4Care Version: V0.1,

Microsoft Pinpoint Guide

Datatekniker med programmering som speciale H5

Gem dine dokumenter i BON s Content Management System (CMS)

Installation og Drift. Aplanner for Windows Systemer Version 8.15

Af: Safa Sarac Klasse 3.4 Skole: Roskilde Tekniske Gymnasium, HTX Vejleder(e): Karl B Dato: 26. marts 2012

Bypassing the. Brian Marick

Erfaringer med CPR-replikering

Indholdsfortegnelse for kapitel 1

Jan Hansen, AMP CMDB Specialist

Flerbruger miljø, opdel database

Softwareløsninger til dit netværk

Installation og Drift. Aplanner for Windows Systemer Version

Overvågningskamera. ~Af Svend, Valdemar og Frederik~

Valgfrit tema. Kommunikation/IT Jannik Nordahl-Pedersen. HTX - Roskilde. Klasse 3.5

KIH Database. Systemdokumentation for KIH Databasen. 1. maj Side 1 af 13

SIMS Active Directory Service 2.5 Quick Guide

Transkript:

Databaser for udviklere () Datamatiker TietgenSkolen Underviser: Allan Helboe 06-06-2010

Problemformulering Denne opgave er et forsøg på at beskrive problemerne der opstår ved anvendelsen af en relationel database som persistenslag, for en objektorienteret applikation. Først og fremmest vil jeg undersøge hvorfor man egentlig anvender relationelle databaser frem for objektorienterede databaser, når de umiddelbart fremstår som et bedre alternativ. Jeg vil derefter undersøge hvordan man kan løse de problemer som objektorienteret data giver i forhold til en relationel database, og vil især gå i dybden med NHibernate som en færdig løsning på problemet. Under dette afsnit vil jeg undersøge hvad der egentlig ligger bag værktøjet, mht. dets historie samt de mønstre der anvendes. Til sidst vil jeg forsøge at anvende NHibernate i en simpel applikation, og hermed få et indblik i processen at arbejde med et ORM-værktøj. Indledning Langt de fleste enterprise applikationer har behov for en løsning til persistent lagring af data. Oftest er det også et krav for disse applikationer, at det samme lager kan anvendes af op til flere samtidige instanser af applikationen, hvilket kan føre til en række af problemer. Dette løses ofte ved at anvende en database til lagring af data, hvilket også medvirker til at der kommer kontrol over samtidigheden i systemet. Nu til dags anvendes der oftest relationelle databaser, men ved anvendelsen af en sådan database indføres dog endnu et stort problem for programmøren: Objektorienterede programmer og relationelle databaser er to ting, der i praksis kan være svære at kombinere. Jeg vil i denne rapport forsøge at finde ud af hvorfor man egentlig ønsker at anvende relationelle databaser, frem for de objektorienterede. Jeg vil derudover undersøge hvilke problemer det medfører at anvende en relationel database, samt hvordan man kan løse disse problemer. Objektorienteret data I den objektorienterede verden anvendes objekter flittigt til opbygningen af en arkitektur med indkapsling af de enkelte kodeelementer. Der er mange fordele ved at programmere objektorienteret, men de største fordele må være følgende: Overskueligheden af koden bliver øget væsentligt ved at ansvaret bliver delt ud. Man har mulighed for at reducere mængden af kode der skal vedligeholdes ved at anvende koncepter som f.eks. nedarvning mellem klasser. Det er muligt at lave en lag-deling af koden som gør refaktorering af eksisterende kode, og tilføjelse af ny funktionalitet sideløbende med det eksisterende, væsentlig lettere. Databaser for udviklere 2

Alt i alt har objektorienteret programmering givet meget i forhold til at gøre kodebasen mere overskuelig, håndterbar og udbygningsvenlig. Styrken i OOP er dog samtidig den største ulempe. Alle data lagres i variabler på objekter, hvilket er meget bekvemt når disse data skal bearbejdes i hukommelsen for en kørende applikation. Når denne applikation skal lukkes ned opstår der dog et problem. Vi ønsker ikke at smide objekterne ud og dermed miste de ændringer der er foretaget, men tværtimod ønsker vi at få persisteret disse objekter sådan at de kan indlæses næste gang applikationen starter. Dette er muligt ved f.eks. en serialisering af det samlede objekt-træ til en fil, men da dette umiddelbart kun fungerer for en enkeltstående applikation, er det ret få enterprisesystemer der kan bruge denne løsning. Vi ønsker i stedet at anvende en database. Databaser Databaser har igennem mange år været anvendt til håndtering af data, både indenfor forretnings- og forskersegmentet. Når vi ser på databaser og objektorienteret data, lyder det meget logisk at man ville anvende en objektorienteret database som persistenslag for en objektorienteret applikation. DBMS en på en OODB er bygget til at håndtere mange af de ting man kunne få brug for når man programmer objektorienteret. Det vil sige at man som udgangspunkt har mulighed for at lagre sine objekter i databasen, samt anvende OO-koncepter, som f.eks. nedarvning mellem klasser, direkte i databasen. En objektorienteret database er derfor umiddelbart, en rigtig god løsning som persistenslag for OO-applikationer. Objektorienterede databaser blev dog først opfundet noget senere end behovet for lagring af data opstod, og derfor har det primært kun været forskerverdenen som har taget dem i brug. Den objektorienterede database er meget velegnet til lagring af komplicerede objekter, da den navigerer og behandler disse objekter væsentlig hurtigere end man ville kunne i en relationel database. Dette er meget velegnet til netop forskerverdenen, men derimod nærmest irrelevant i forhold til enterprise-applikationer. Her anvendes databaser normalt til lagring af væsentlig simplere datastrukturer, hvorfor en relationel database er mere anvendelig. I modsætning til den konceptuelle datamodel man anvender i objektorienterede databaser, findes den relationsbaserede datamodel 1 som anvendes i relationelle databaser. Relationsbaseret data består af data med interne relationer mellem de forskellige dele af dataene. Databaserne har en del fordele ved bl.a. ved at være hurtige at søge i, man kan lave meget specifikke forespørgsler på kryds og tværs af tabeller og en korrekt normaliseret relationel database gør det endda muligt at opdatere dele af det samlede data uden at låse uberørte dele af databasen. Den relationelle databasemodel blev opfundet i 1969 og har siden hen dannet grundlag for langt de fleste enterprise-systemer. Det er uden tvivl indenfor forretningsverdenen at der er 1 Relationel Model (se kildeangivelse side 7) Databaser for udviklere 3

flest penge at tjene, hvilket også har ført til at der gennem tiden er blevet fokuseret meget på udviklingen indenfor dette segment. Optimeringerne af databaserne er sket både ydelsesmæssigt f.eks. i form af optimerede algoritmer og indeks-strukturer, samt sikkerhedsmæssigt hvor transaktionsstyringen bliver bedre og bedre til at sikre mod inkonsistens under samtidige operationer i databasen. Det at de relationelle databaser har et så kraftigt segment i ryggen, gør altså at de på mange punkter, er de objektorienterede databaser overlegne. Det er derfor også meget attraktivt at kunne anvende de relationelle databaser, selvom man faktisk anvender objektorienteret programmering. De relationelle databaser og den konceptuelle datamodel er dog to ting der ikke umiddelbart kan kombineres. Nedenfor ses et klassediagram over klasserne Skole og Elev. Der kan under en skole tilknyttes et vilkårligt antal elever. Dette ville i en konceptuel model oftest implementeres ved hjælp af en collection af Elev på Skole klassen. Ser vi på samme eksempel oprettet i en relationel database ville det fremstå som nedenstående. Første tabel vil indeholde alle skolerne i systemet. Derudover ville man skulle bruge en tabel til elevernes data. For at indikere tilknytningen til den enkelte skole, er det nødvendigt at lave en fremmednøgle til Skoler-tabellen. Denne oprettes som en ekstra attribut på Elever-tabellen og man vil derefter så kunne joine Skoler-tabellen på Elever-tabellen. Som ovenstående eksempel illustrerer, er det to vidt forskellige måder at arbejde på, selv når man taler om opbevaring af simple datastrukturer. Hvis man så begynder at tænke på koncepter som f.eks. lagring af nedarvede objekter, bliver problemet kun endnu større. Data mapping For at løse problemet med forskellen fra den relationelle model til den konceptuelle model, har man gennem tiden opfundet forskellige løsninger. Fælles for dem alle er, at det arbejde der udføres, er en mapning mellem databasens tabeller og de objekter man arbejder med i hukommelsen. Disse løsninger betegnes som data abstraktions lag, og placeres mellem domænelaget og selve databasen. Man kan betegne data abstraktions laget som en tolk der kan arbejde med objekter i applikationen, og med et vilkårligt sprog i den underliggende datakilde. Databaser for udviklere 4

Mapning går derfor ud på at man laver et led imellem værdierne som gemmes på objekterne i hukommelsen, ned i de tilsvarende tabeller i databasen. Selvom denne mapning lyder ret simpel, har den også potentiale til at give virkelig meget arbejde. Afhængigt af hvor kompliceret en domæne-model man arbejder med, kan vedligehold af ens mapninger til databasen hurtigt blive et utroligt omfattende og uoverskueligt stykke arbejde. Det kan desuden være svært at få anvendt begreber som transaktionsstyring og lazy-loading, hvis man selv programmerer ens SQL kald direkte i data abstraktions laget. Heldigvis er det et kendt problem, og der er derfor kommet adskillige værktøjer som har til formål at hjælpe med at få gjort mapningen mellem modellen og databasen, altså udarbejdelsen af data abstraktions laget, så smertefri som muligt for udvikleren. Disse værktøjer bliver betegnet som ORM-værktøjer (). Et af de mere kendte værktøjer er Hibernate-frameworket til Java, som blev udgivet i første udgave i 2001. Dette værktøj er et framework til at indbygge i applikationer, som gør det muligt at få mappet rækker i tabellen over til data der kan arbejdes med i applikationen. Hibernate frameworket blev hurtigt ret populært idet det er open source, og selvom der findes utallige alternativer må Hibernate anses som værende en af de mest kendte. Da Hibernate er baseret på Java, er det ikke muligt at anvende det i.net miljøet. Heldigvis er projektet dog blevet porteret til.net platformen under navnet NHibernate. Udviklingen er på nuværende tidspunkt drevet af et meget aktivt community, hvilket vil sige at der konstant bliver lavet forbedringer og rettelser, når der opdages fejl eller nye gode ideer. NHibernate anses derfor som værende et af de førende ORM værktøjer til.net platformen, ved siden af produkter som SubSonic, Persistor, Linq-2-SQL og Microsofts Entity Framework. Bag om NHibernate NHibernate blev udgivet i 2005, af Tom Barrett. Det er efterfølgende blevet kastet lidt frem og tilbage mellem en række forskellige udviklere som har været ansvarlige for projektet, for til sidst at ende som et community-drevet open-source projekt. Værktøjet består af en række.dll-filer man indlejrer i sit projekt og herefter har man et framework til data adgang man kan programmere op imod. NHibernate understøtter en række forskellige databaser, hvilket faktisk gør det muligt at have den samme kodebase til at understøtte forskellige databaser uden at skulle ændre i programkoden. Man programmerer imod NHibernate-laget og NHibernate klarer så adgangen til databasen via de konfigurationer man angiver. NHibernate er baseret på XML-filer til både konfiguration og mapning, hvilket for nye brugere kan virke en smule uoverskueligt at komme i gang med. Det er også et af de meget store kritikpunkter for NHibernate, at indlæringskurven kan virke rimelig stejl. Som alternativ til XML-filerne kan man hente Fluent NHibernate 2, der gør det muligt at konfigurere NHibernate 2 Fluent NHibernate (se kildeangivelse på side 8) Databaser for udviklere 5

direkte i stærkt typet kode, med en mere programmør-venlig syntaks. Denne tilgang er noget mere overskuelig og fleksibel, hvilket har gjort det til praksis at man ofte anvender Fluent i begyndelsesfasen hvor man har mange ændringer i arkitekturen, for så at skifte til den XMLbaserede konfiguration, når arkitekturen er fastlagt. Der findes en række forskellige mønstre der kan anvendes, når man taler om database mapning. De to mest brugte er Active Record 3 og Repository 4. Det er derfor også de to typiske løsninger der bruges med NHibernate. Repository kan anses som værende en database-controller som sørger for al kommunikation med databasen. Den adskiller i høj grad modellen fra selve datalaget, da man har en hel separat klasse der arbejder med objekter på den ene side, og persistenslaget (via NHibernate) på den modsatte side. Ønsker man at gemme data i databasen, sendes dette objekt til Repository et som så tager sig af resten. Det er også igennem Repository et at updates og deletes foretages. Ønsker man at hente data ud af databasen, kalder man Repository et med de kriterier ens query har. Repository et udfører så et query via NHibernate og sender objekter retur til kalderen. Active Record er en smule anderledes, da man i dette mønster gør de enkelte objekter ansvarlige for at opdatere sig selv i databasen. Det vil sige at foretages der en ændring, er det objektet selv der kender til databasen og hermed er ansvarlig for at ændringen persisteres. Når objekter indlæses, indeholder de også selv koden til at indlæse deres attributter direkte fra databasen. Forskellen mellem de to mønstre er primært hvor man placerer kendskabet til persistenslaget. Repository fremlægges af Martin Fowler som værende bedre til større og mere komplicerede systemer, hvor Active Record er fint til mindre systemer. Jeg finder det dog mere overskueligt at anvende Repository selv i mindre systemer, og med NHibernate som en hjælp til udarbejdelsen af koden, er det virkelig ikke meget mere arbejde man lægger i at få en væsentlig mere overskuelig løsning. Transaktioner er også væsentlig lettere at implementere i en Repository-baseret løsning frem for en Active Record løsning. Begge dele er muligt, men eftersom man under Repository, samler alle databaseoperationer i én klasse, er det noget nemmere at implementere transaktioner ved udførsel af flere handlinger, i dette mønster. Anvendelse af NHibernate Under sammenligningen mellem den konceptuelle og den relationelle model, anvendte jeg et eksempel med skoler og elever. Dette er et godt eksempel til at demonstrere brugen af NHibernate, da det har relationer mellem data, og samtidig kan laves uden at der behøver programmeres andet end skelettet af en model samt selve datalaget. Jeg har valgt at 3 Martin Fowler Patterns of Enterprise Application Architecture (s. 160) 4 Martin Fowler Patterns of Enterprise Application Architecture (s. 322) Databaser for udviklere 6

programmere en løsning 5 baseret på Repository-pattern, da denne virker som den mest anvendte løsning, samt den der formår at give den mest klare adskillelse af datalag og model. Til løsningen bruger jeg Fluent NHibernate tilføjelsen, da den gør det væsentligt lettere for nybegyndere at starte med NHibernate. De grundlæggende klasser der arbejdes ud fra er Skole og Elev, hvor methods bliver erklæret som virtual så de senere kan overrides. Når disse klasser er defineret, oprettes der mapninger som beskriver hvordan værdierne på klasserne, skal gemmes i databasen. Her defineres ved hjælp af lambda udtryk at der skal oprettes et ID som svarer til ID et på objektet, samt at der oprettes mapninger til de enkelte attributter. I mapningen for Skoleobjektet defineres desuden en 1-til-mange relation på Elever, hvilket hjælper NHibernate til at vurdere hvordan tabellerne skal opbygges. Jeg anvender i denne løsning Eager-loading da der ikke umiddelbart er et behov for lazy-loading. De klasser vi har nu, fortæller NHibernate hvordan objekterne skal gemmes. Det eneste der så umiddelbart mangler er selve konfigurationen til NHibernate som beskriver hvor vi ønsker at den skal arbejde. Dette gøres i repository klassens constructor, hvor vi både opretter en konfiguration samt et session factory. 5 Den færdige løsning kan hentes via link i kildeangivelsen (side 9) Databaser for udviklere 7

Da Repository et har til formål at være ansvarlig for adgangen til databasen, er det desuden nødvendigt at der er implementeret funktioner til at lave CRUD 6 -operationer. Disse er ret simple og anvender en session fra Session Factory et til at oprette en transaktion hvori der så bliver udført de nødvendige operationer. Idet der anvendes using sætninger, lukkes både transaktionen og sessionen ned igen. Vælger man ikke at bruge using, er det vigtigt at huske at lukke forbindelserne igen, da forbindelser til serveren er dyre og bør lukkes ved endt brug. Vi har nu defineret selve data adgangen, og der er derfor kun tilbage at anvende repository et. Jeg har lavet en simpel test hvori jeg opretter en række objekter og derefter anvender instanser af repository-klassen til at gemme disse objekter i databasen. En instans af repository-klassen er ansvarlig for at gemme en bestemt slags objekt i databasen, og det er derfor nødvendigt at oprette et repository både for Skole og Elev. Repository-klassen er dog generisk og kan derfor anvendes med vilkårlige klasser som arbejdsobjekter, uden at der skal ændres i den. Til sidst oprettes der nye objekter i modellen, som oprettes via et query gennem repositoryklassen og man kan dermed konstatere at NHibernate har hentet objekterne fra databasen. Hvis man tager et kig på databasen via Management Studio ser man også at NHibernate automatisk har oprettet tabeller meget lig de tidligere nævnte i rapporten, med de korrekte data. 6 Create-Read-Update-Delete basis funktioner for et datalag. Databaser for udviklere 8

Konklusion Jeg har gennem udarbejdelsen af rapporten fået øget mit kendskab til de problemer der kan opstå under anvendelse af objektorienteret programmering og relationelle databaser. Jeg har desuden fået læst om de tilgængelige værktøjer til afhjælpning af denne problematik og konkluderet at NHibernate angiveligt virker som det mest anvendte ORM-værktøj indenfor.net verdenen. Dette værktøj valgte jeg at afprøve for at se hvordan det virkede samt om det var til at finde ud af, eller om der var hold i de kritikpunkter der har været nævnt mht. sværhedsgraden. Efter at have arbejdet med værktøjet kan jeg konkludere at det ved hjælp af Fluent NHibernate faktisk er rimelig overskueligt at komme i gang med at bruge NHibernate. Det virker som det skal, og løser rigtig meget af det manuelle arbejde der ville være i at skrive en database-mapper selv. Desuden er det rigtigt nemt at omkonfigurere Fluent NHibernate hvis der opstår en ændring i opbygningen af databasen, hvilket ville være et større stykke arbejde med en manuel datamapper. Min konklusion er at NHibernate bestemt er besværet værd da det løser utrolig mange af de problemer der måtte være. Det kan være svært at komme i gang med, men når man først har fået fat i det, virker det som et rigtig godt og gennemført værktøj. Databaser for udviklere 9

Kildeangivelser Anvendelse af NHibernate (NHibernateEksempel.zip) http://dl.dropbox.com/u/4515894/nhibernateeksempel.zip Patterns of Enterprise Application Architecture Martin Fowler (Addison Wesley) ISBN-13: 978-0321127426 Relationel Model Wikipedia http://en.wikipedia.org/wiki/relational_model NHibernate Forge http://nhforge.org Fluent NHibernate http://fluentnhibernate.org NHibernate Wikipedia http://en.wikipedia.org/wiki/nhibernate ADO.NET Entity Framework - Wikipedia http://en.wikipedia.org/wiki/ado.net_entity_framework Databaser for udviklere 10