2006-05-15

O/R-mapping - vad är det?

En vanlig modell vid programmering mot databaser är att all logik för att kommunicera med databasen placeras i ett separat lager, ett så kallat data access layer (DAL, även data access logic). Detta lager innehåller vanligtvis en mängd olika CRUD-metoder (Create-Read-Update-Delete) som använder hårdkodade SQL-frågor och/eller anrop av lagrade procedurer för att returnera datatransfer objects (DTO, t.ex. DataSet) eller "business objects" (t.ex. Customer, Product) till anropande lager. Så här brukar det, något förenklat, se ut i koden:

Person myPerson = dataAccessLayer.GetPerson(id);
myPerson.Name = "Nytt namn";
dataAccessLayer.SavePerson(myPerson);

Mönstret känns igen från Microsofts egna kodexempel, liksom från deras architecture guidelines och best practices.

En annan modell är så kallad Object Relational Mapping eller O/R-mapping (även automated mapping). Vissa skulle säga att O/R-mapping är ett mer objektorienterat sätt att närma sig problemet; i denna modell skapar man "mappningar" mellan databasen tabeller/vyer och deras fält, och objektorienterade klasser och deras attribut. Detta görs enklast via en O/R-mapper som förutom att automatiskt generera klasserna utifrån databasen, även innehåller ett ramverk som bland annat genererar dynamisk SQL för att hantera kommunikationen mellan objekten och databasen. Med en O/R-mappers dynamiska SQL och ramverk blir det också enkelt att byta databas; koden ser likadan ut, men annan kod genereras och de dynamiska SQL-satserna kanske ser annorlunda ut. Så här kan koden se ut med en O/R-mapper:

Person myPerson = new Person(id);
myPerson.Name = ”Nytt namn”;
myPerson.Save();

Man skulle kunna säga att en O/R-mapper låter den objektorienterade utvecklaren att spara objektens tillstånd (”state”) utan att behöva tänka på var och hur detta sker.
Förespråkare för O/R-mapping brukar framhålla fördelarna med det automatiska kodgenererandet; förutom den uppenbara tidsbesparingen minskar även risken för buggar. Det är onekligen ett tilltalande argument, men det finns bra verktyg för att automatiskt generera DAL även utan O/R-mapping. Ett exempel är DataSet Designer i Visual Studio, ett annat och mer kraftfullt är CodeSmith. O/R-mapperns dynamiska natur gör dock att du redan från början har en väldigt komplett lösning, medan du med en traditionell kodgenerator kan få lägga ned en hel del arbete på att finjustera mallar och annat för att få fram kod som är lika flexibel.

Modellen har förstås sina kritiker också. Den vanligaste invändningen är att O/R-mappers dynamiska SQL förvisso är flexibel, men att det man vinner i flexibilitet lätt kan förloras i prestanda; en skicklig databasutvecklare kan optimera enskilda frågor, särskilt mer komplicerade sådana, bättre än en O/R-mapper. En del kritiker menar till och med att många som använder O/R-mappers gör det därför att de inte kan sin SQL; intressant nog finns det dem som menar att det är en fördel med O/R-mappers att de genererar bättre SQL än en normal utvecklare. Frågan är hur allvarlig denna kritik är – de flesta O/R-mappers erbjuder en möjlighet att gå runt ramverket och specialskriva metoder och använda lagrade procedurer.

O/R-mapping är ingenting nytt, men jag tycker det talats allt mer om modellen på sistone. Jag tror att en del av förklaringen kan vara att Microsoft, från att ha varit ganska ointresserade av modellen och satsat mer på data transfer objects som recordsets och datasets, för en tid sedan började tala om egen O/R-mapper. Arbetsnamnet var ObjectSpaces och tanken var att det skulle lanseras med Visual Studio 2005. Samtidigt som detta ökade intresset för O/R-mapping hade det på kort sikt en motsatt effekt; man väntade hellre på Microsofts lösning än investerade tid och resurser på en produkt med osäker framtid. En hel del hann dock hända på vägen, ObjectSpaces lades ned och allt talar nu för att det är LINQ/dLINQ, som jag skrivit om tidigare, som kommer att bli Microsofts bidrag till O/R-mapping. Om jag förstått saken rätt kommer LINQ dessutom att vara utbyggbart på ett sådant sätt att dagens O/R-mappers kommer att kunna bygga på LINQ i framtiden, snarare än konkurrera med teknologin.

Till syvende og sist blir det som vanligt projektets förutsättningar som får bestämma om man bör använda en O/R-mapper eller inte. I väldigt många projekt räcker en O/R-mapper väldigt långt och du får väldigt mycket gratis, i en del fall kanske det krävs mycket specialskriven dataaccesslogik som gör att en O/R-mapper inte tillför särskilt mycket. Ibland kanske det är fråga om så pass lite affärslogik att det blir suboptimalt att baka om data till objekt, till exempel i rapporter som utgår från en tabell eller vy i databasen.

Oavsett om man tycker att O/R-mapping är en bra modell eller inte kan man vara säker på att vi kommer att se ännu mer av den i och med LINQ som kommer med nästa version av C#/VB.NET och Visual Studio redan i höst. Vill man inte använda en O/R-mapper bör man i alla fall titta närmare på kodgeneratorer; här är trenden än tydligare – allt mer kod kommer i framtiden att genereras av olika verktyg.

Länkar till information om O/R-mapping och LINQ

1 kommentar(er):

Anonym sa...

Intressant och bra artikel. Lyssna gärna in min podcast med Mats Helander om detta ämne.

http://buzzfrog.blogs.com/zabrak/2006/05/av_56_samtal_me.html

/dag