När du utvecklar omfattande applikationer kommer du nästan oundvikligen att stöta på behovet av att interagera med en databas. En sådan applikation kräver att du implementerar CRUD-operationer, det vill säga förmågan att skapa, läsa, uppdatera och radera information.
För att hantera detta krävs en databas. Om du skapar ditt program med ett objektorienterat programmeringsspråk som JavaScript och använder en relationsdatabas som MySQL, kan det vara utmanande att arbeta med databasen direkt.
Som JavaScript-utvecklare måste du även beakta de komplicerade detaljerna i relationsdatabasen och sätta dig in i dess syntax samt hur man konstruerar komplexa SQL-frågor som applikationen kan behöva.
Kom ihåg att relationsdatabaser lagrar data i tabeller med rader och kolumner, medan JavaScript arbetar med objekt och relationer mellan dem. Detta kan vara både tidskrävande och komplicerat, vilket motiverar användningen av en Object Relational Mapper (ORM).
Object Relational Mapper (ORM)
En ORM är ett verktyg som underlättar för utvecklare att hantera relationsdatabaser med hjälp av objektorienterade principer.
En ORM fungerar som en länk mellan applikationens kod och den valda relationsdatabasen. Detta gör att utvecklare kan interagera med databasen med samma objektorienterade metoder som används i applikationens kod.
ORM:en mappar relationsdatabastabeller till klasser, där varje klassinstans representerar en rad eller ett dataregister i tabellen. Klassattribut används för att återspegla kolumner i tabellen.
Detta innebär att utvecklare kan använda det programmeringsspråk de föredrar för att skapa, läsa, uppdatera, radera och hantera data som lagras i databasen, utan att behöva skriva komplicerade SQL-kommandon.
Genom att använda en ORM reduceras mängden SQL-kod du behöver läsa, och du slipper lära dig ett nytt frågespråk bara för att hantera databasen.
För att illustrera hur en ORM fungerar, betrakta följande MySQL-fråga som söker efter användare i IT-avdelningen:
SELECT * FROM users WHERE department="IT";
Samma operation kan utföras med hjälp av en JavaScript ORM, som visas nedan. Observera användningen av vanlig JavaScript-kod för att utföra samma fråga.
const users = await User.findAll({ where: { department: 'IT', }, });
Fördelar med att använda en ORM
Här följer några fördelar som JavaScript-utvecklare kan uppnå genom att använda en ORM:
Abstraktion av databaskomplexitet
ORM:er döljer komplexiteten i den underliggande databasen. Det gör att utvecklare kan interagera med databasen genom sitt backend-språk i stället för att skriva invecklad SQL-kod.
Vissa ORM:er erbjuder även frågebyggare, vilket gör det enkelt att skapa komplexa frågor med hjälp av objektorienterade metoder. Detta resulterar i renare, mer underhållbar kod som är enklare att felsöka och uppdatera.
Ökad produktivitet
ORM:er abstraherar bort svårigheten med att skriva SQL-frågor direkt och hantera databasinteraktioner. Detta gör att utvecklare kan fokusera på applikationens affärslogik, vilket är den viktigaste delen av applikationen.
Utvecklare kan dessutom interagera med databaser i ett mer bekant objektorienterat mönster, utan att behöva skriva mycket kod eller utföra repetitiva uppgifter.
ORM:er kan även användas för att automatiskt fylla databaser med startdata och generera kod för dataåtkomst. Dessa faktorer ökar avsevärt utvecklarnas produktivitet.
Databasoberoende
En viktig egenskap hos ORM:er är att de låter dig skriva applikationskod på ett sätt som är oberoende av databasen. Därmed blir din applikationskod inte låst till en specifik databas, och du kan enkelt byta databas utan att behöva göra större ändringar i koden.
Detta är särskilt viktigt när en applikation behöver utvecklas vidare eller stödja flera databaser samtidigt.
Enkel hantering av scheman och relationer
ORM:er förenklar arbetet med databasscheman och hanteringen av relationer mellan olika databasenheter.
Vissa ORM:er erbjuder automatisk generering av scheman utifrån befintliga databaser, och de flesta tillhandahåller metoder för att enkelt definiera och hantera relationer mellan tabeller i databasen.
Förbättrad säkerhet
ORM:er erbjuder förbättrad databassäkerhet eftersom de filtrerar data och använder parametriserade frågor internt. Parametriserade frågor innebär att SQL-frågor använder platshållare för indatavärden i stället för att direkt inkludera användarindata.
På så vis infogas aldrig användarindata direkt i en SQL-fråga. Detta gör att ORM:en skyddar din applikation mot SQL-injektionsattacker, vilket förbättrar applikationens säkerhet.
Nackdelar med att använda en ORM
Trots de många fördelarna med ORM finns det även några nackdelar. Eftersom de lägger till ett abstraktionslager ovanpå databasen kan det leda till prestandaförluster och högre minnesanvändning.
Utöver detta kräver användning av en ORM att utvecklaren sätter sig in i hur den fungerar, och de behöver även ha grundläggande kunskaper om SQL för att förstå vad varje kommando faktiskt gör.
Med det sagt är ORM fortfarande ett mycket användbart verktyg för utvecklare och det bästa sättet att interagera med relationsdatabaser från applikationer som bygger på objektorienterade metoder. För att hjälpa dig att komma igång med en ORM, följer här några av de mest populära ORM:erna för JavaScript-applikationer.
Sequelize
Enligt den officiella dokumentationen är Sequelize en modern TypeScript och Node.js ORM för databaser som Oracle DB, PostgreSQL, MySQL, MariaDB, SQLite, Microsoft SQL Server, IBM DB2 och Snowflake. Sequelize är en ORM med öppen källkod som är mycket populär bland utvecklare som använder Node.js-ramverket tillsammans med relationsdatabaser.
Detta kan tillskrivas dess robusta uppsättning funktioner som underlättar arbetet med relationsdatabaser i Node.js. Sequelize är exempelvis en löftesbaserad ORM, vilket innebär att den har stöd för löften, en kärnfunktion i Node.js-ramverket.
Dessutom stöder Sequelize ivrig laddning, där resurser laddas så snart applikationskoden körs, och lat laddning, där resurser inte laddas förrän de faktiskt behövs. Sequelize har även gediget stöd för transaktioner, läsreplikering och modellvalidering. Den tillåter även databasmigrering och synkronisering.
Användare kan även definiera relationer mellan modeller när de använder Sequelize. ORM:en erbjuder dessutom ett brett utbud av frågealternativ, som gör att utvecklare enkelt kan konstruera komplexa databasfrågor.
Prisma
Prisma är en öppen källkod-ORM som förenklar hanteringen och interaktionen med din databas från alla JavaScript- eller TypeScript-miljöer.
Prisma har stöd för PostgreSQL, MySQL, Microsoft SQL Server, CockroachDB, SQLite och MongoDB. Dessutom integreras den enkelt med alla JavaScript- eller TypeScript-ramverk, förenklar databaser och förbättrar typsäkerheten.
För att underlätta skapandet av frågor har Prisma en funktion kallad Prisma Client. Den ger autokomplettering och gör att utvecklare kan skapa typsäkra frågor som är anpassade till schemat i applikationen.
Utvecklare kan skapa sitt eget schema från grunden eller använda Prisma för att automatiskt generera scheman genom att undersöka en befintlig databas.
En annan Prisma-funktion är Prisma Migrate, ett verktyg för migrering av Prisma-scheman. Verktyget genererar anpassningsbara SQL-migreringar, vilket ger användarna full kontroll och flexibilitet när de distribuerar applikationer från utvecklings- till produktionsmiljöer.
Slutligen har Prisma-användare tillgång till Prisma Studio, ett administratörsgränssnitt där de kan se, utforska, manipulera och förstå data i databasen. Sammantaget är Prisma en utmärkt ORM för JavaScript- och TypeScript-utvecklare.
TypeORM
TypeORM är en ORM med öppen källkod som skapades för att stödja de senaste JavaScript-funktionerna och tillhandahålla ytterligare funktionalitet som gör att utvecklare kan skapa alla typer av applikationer som använder databaser.
TypeORM har stöd för MySQL, MariaDB, PostgreSQL, CockroachDB, SQLite, Microsoft SQL Server, Oracle, SAP Hana och sql.js.
TypeORM stöder programmeringsspråken JavaScript och TypeScript, och även MongoDB, som inte är en relationsdatabas. TypeORM fungerar i Node.js, webbläsare, Ionic, Cordova, React Native, NativeScript, Expo och Electron-plattformar.
TypeORM gör att utvecklare kan arbeta med flera databastyper och använda flera databasinstanser. Den har även stöd för cachning, loggning, transaktioner, relationer, ivriga och lata relationer samt migrering och automatisk migrering.
TypeORM stöder även DataMapper, ActiveRecord, strömmande råresultat, databasöverskridande och schemaöverskridande frågor och ger användarna en kraftfull frågebyggare.
MikroORM
MikroORM är en TypeScript ORM med öppen källkod som stöder MySQL, MariaDB, PostgreSQL, SQLite och MongoDB. Denna ORM bygger på Datamapper, Identity Map Pattern och Unit of Work. Unit of Work används för att hålla reda på alla entiteter som påverkas av en affärstransaktion och koordinerar även hur ändringarna skrivs.
Detta har fördelen att möjliggöra automatisk hantering av transaktioner, automatisk batchning av frågor och direkt implementering av affärs- eller domänlogik direkt i de entiteter som används.
MikroORM levereras också med en metadatasbaserad QueryBuilder med stöd för automatisk koppling och ett händelsesystem som kan användas för att ansluta till entitetens livscykel och ändra hur UnitOfWork fungerar.
Att fylla databaser med startdata, så kallad seeding, är enkelt med MikroORM eftersom den har en seeder som gör att du kan generera falsk data i valfri mängd eller form och använda den för att fylla din databas.
Slutligen stöder MikroORM enkla databasmigreringar.
Bookshelf.js
Bookshelf är en JavaScript-ORM med öppen källkod för Node.js. Syftet med denna ORM är att tillhandahålla ett enkelt bibliotek som kan användas för vanliga uppgifter när man hanterar databaser i JavaScript och skapar relationer mellan objekten. Bookshelf är utvecklat för att fungera med PostgreSQL, MySQL och SQLite3.
Eftersom Bookshelf är en Node.js ORM stöder den både löften och traditionella återanrop när du interagerar med ORM:en från en Node.js-applikation. Den har även stöd för transaktioner, polymorfa relationer, ivrig/kapslad relationsladdning och en mängd olika typer av relationer.
Även om Bookshelf inte har samma funktionsrikedom som andra ORM:er, utmärker den sig genom sin enkelhet, flexibilitet och hur lätt det är att läsa, förstå och utöka dess kodbas. Bookshelf är ett utmärkt val om du behöver en enkel och smidig ORM för dina JavaScript-projekt.
Node ORM2
Node ORM2 är en enkel och lätt Node.js ORM som stöder MySQL, SQLite och Progress OpenEdge-databaser. Denna ORM gör det enkelt att arbeta med modeller i Node.js. Du kan enkelt skapa, synkronisera, ta bort, hämta, söka, radera, räkna och massskapa datamodeller.
Du kan även skapa relationer mellan modeller och definiera anpassade valideringar utöver de inbyggda valideringar som finns. Node ORM2 implementerar singleton-beteende, vilket säkerställer att du alltid får samma objekt som representerar samma rad när du hämtar den flera gånger.
Waterline
Waterline är en adapterbaserad ORM för Node.js. Den är även standard-ORM som följer med webbutvecklingsramverket Sails. Waterline kan dock även användas utan Sails-ramverket.
Eftersom Waterline är en adapterbaserad ORM, har den stöd för att hantera flera databassystem med hjälp av adaptrar. Officiellt stödda databaser inkluderar MySQL, PostgreSQL, MongoDB, Redis och lokal lagring.
Waterline har även community-utvecklade adaptrar för CouchDB, SQLite, Oracle, Microsoft SQL Server, DB2, Riak, neo4j, OrientDB, Amazon RDS, DynamoDB, Azure Table, RethinkDB och Solr.
Waterline gör att du kan använda mer än en databas i ditt projekt, och den erbjuder ett enhetligt API för att hantera olika databaser och protokoll. Det innebär att kod som skrivits med Waterline ORM kan fungera med alla databaser som ORM:en stöder, utan att du behöver ändra koden.
Dessutom har Waterline utvecklats med fokus på modularitet, testbarhet och konsekvens mellan adaptrar, vilket gör den enkel att använda och integrera med olika databaser.
Objection.js
Objection.js är en ORM som strävar efter att inte vara i vägen för utvecklaren och som gör det enkelt att använda all kraft i SQL och den underliggande databasmotorn.
Den erbjuder alla fördelar med en SQL-frågebyggare och är kraftfull för att underlätta hanteringen av relationer. En SQL-frågebyggare är ett verktyg som förenklar processen att skapa komplexa SQL-frågor.
Objection.js erbjuder ett enkelt sätt att definiera modeller och relationer mellan dem, med fullständiga CRUD-funktioner (Create, Read, Update, Delete) som utnyttjar hela SQL-kraften. Den erbjuder också lättanvända transaktioner.
Användare kan även utföra ivrig laddning, infoga och uppdatera objektgrafer, lagra komplexa dokument som enstaka rader och använda JSON-schemavalidering. Objection.js har officiellt stöd för programmeringsspråken TypeScript och JavaScript.
Slutsats
Som utvecklare som arbetar med relationsdatabaser från en JavaScript- eller TypeScript-applikation är det fördelaktigt att använda en ORM för att interagera med databasen.
Det förenklar inte bara databasinteraktionerna, utan ökar även din produktivitet, minskar mängden SQL-kod du behöver skriva och förbättrar applikationens säkerhet.
När du ska bestämma vilken ORM du ska använda, kan du överväga att använda någon av de ORM:er som nämns i artikeln, beroende på vilka funktioner som bäst passar den applikation du bygger.
Du kan även utforska de bästa JavaScript-kompilatorerna online.