Wat is een ORM? Hoe apps met databases praten, uitgelegd
Een ORM (object-relational mapper) is een codebibliotheek die tussen een app en een relationele database zit. In plaats van databasequery's in SQL te schrijven, werken ontwikkelaars met gegevens als gewone objecten in hun programmeertaal — db.booking.create(...) of Booking.find(...) — en vertaalt de ORM dat naar SQL, voert het uit en zet de resultaten terug in objecten. Bekende voorbeelden zijn Prisma en Drizzle voor TypeScript, SQLAlchemy voor Python en Entity Framework Core voor C#.
Waarom ORM's ertoe doen als je met AI bouwt
Als een AI-appbouwer een database aan je app toevoegt, voegt hij meestal ook een ORM toe om ermee te praten. Je hoeft geen ORM-code te schrijven, maar het helpt om te weten dat hij er is:
- Je datamodel staat in code. Het schemabestand van de ORM is vaak de duidelijkste beschrijving van de gegevens van je app: welke tabellen er zijn, welke velden elke tabel heeft en hoe ze met elkaar verbonden zijn. Het lezen ervan is een snelle manier om te controleren of de AI je app goed heeft begrepen.
- Wijzigingen in de database lopen via migraties. Wanneer je vraagt ‘voeg een telefoonnummer toe aan klanten’, past de AI het model aan en maakt hij een migratie. Dat helpt begrijpen waarom een wijziging eerst moet worden toegepast voordat hij live werkt.
- Veilig by default. ORM's bouwen query's zo op dat ze beschermd zijn tegen SQL-injectie, een van de meest voorkomende beveiligingslekken in apps die query's met de hand in elkaar zetten.
- Prestatievalkuilen. ORM's maken het makkelijk om per ongeluk honderden kleine query's uit te voeren waar er één genoeg was. Dat is een veelvoorkomende oorzaak van trage pagina's in met AI gebouwde apps.
Een alledaagse vergelijking
Stel je een Britse reiziger en een Japanse winkelier voor die geen gemeenschappelijke taal spreken en via een tolk communiceren.
De reiziger (je app) zegt: ‘Ik wil de drie goedkoopste thee’s die u heeft.’ De tolk (de ORM) vertaalt dat in precies Japans (SQL), geeft het door aan de winkelier (de database) en vertaalt het antwoord terug naar het Engels.
De reiziger leert nooit Japans, en voor de meeste gesprekken is dat prima. Maar bij een ingewikkelde onderhandeling helpt het om direct te spreken — daarom laten de meeste ORM's ontwikkelaars ruwe SQL schrijven wanneer dat nodig is.
Hoe een ORM werkt
Databases zoals Postgres slaan gegevens op in tabellen met rijen en kolommen en worden bevraagd met SQL. Programmeertalen werken met objecten: een boeking met een datum, een klant en een status. De ORM koppelt het ene aan het andere:
| Databasekant | ORM- / codekant |
|---|---|
Tabel bookings | Model Booking |
| Rij | Eén boekingsobject |
Kolom starts_at | Veld startsAt |
Vreemde sleutel customer_id | Relatie booking.customer |
SELECT, INSERT, UPDATE, DELETE | Methoden find, create, update, delete |
Deze vier bewerkingen zijn de CRUD-acties waarop bijna elke app is gebouwd.
Een uitgewerkt voorbeeld: boekingen met Prisma
Hier is een vereenvoudigd Prisma-schema voor een app voor salonafspraken. Het beschrijft twee tabellen en hoe ze verbonden zijn:
model Customer {
id Int @id @default(autoincrement())
name String
email String @unique
bookings Booking[]
}
model Booking {
id Int @id @default(autoincrement())
startsAt DateTime
service String
customer Customer @relation(fields: [customerId], references: [id])
customerId Int
}
In gewone woorden: een klant heeft een naam, een unieke e-mail en veel boekingen; elke boeking heeft een starttijd, een dienst en hoort bij één klant.
Nu wil de app ‘de aankomende boekingen van Lena, de eerstvolgende eerst’:
const bookings = await db.booking.findMany({
where: {
customer: { email: "lena@example.com" },
startsAt: { gte: new Date() },
},
orderBy: { startsAt: "asc" },
});
De ORM vertaalt dat ongeveer naar onderstaande SQL, voert die uit en geeft een lijst met boekingsobjecten terug:
SELECT b.* FROM "Booking" b
JOIN "Customer" c ON c.id = b."customerId"
WHERE c.email = $1 AND b."startsAt" >= $2
ORDER BY b."startsAt" ASC;
De $1 en $2 zijn plaatshouders: het e-mailadres en de datum worden los van de querytekst verstuurd, en dat voorkomt SQL-injectie.
Migraties
Vraag je daarna ‘laat klanten een telefoonnummer toevoegen’, dan voegt de AI phone String? toe aan het model Customer (het ? betekent optioneel) en genereert hij een migratie — een klein SQL-script zoals ALTER TABLE "Customer" ADD COLUMN "phone" TEXT;. Migraties worden in volgorde opgeslagen, zodat elke kopie van de database naar dezelfde structuur kan worden gebracht, en de geschiedenis van wijzigingen blijft bewaard.
Veelgebruikte ORM's per taal
| Taal | Veelgebruikte ORM's |
|---|---|
| TypeScript / JavaScript | Prisma, Drizzle, TypeORM, Sequelize |
| Python | SQLAlchemy, Django ORM, SQLModel |
| C# | Entity Framework Core |
| Java | Hibernate (vaak via Spring Data JPA) |
| Ruby | Active Record |
ORM's verschillen in hoeveel ze SQL verbergen. Prisma gebruikt een eigen schemataal en querystijl; Drizzle blijft bewust dicht bij de vorm van SQL en is toch volledig getypeerd. Lichtere hulpmiddelen die query builders heten, zoals Knex of Kysely voor TypeScript, helpen SQL in code op te bouwen zonder rijen aan volledige objecten te koppelen.
Belangrijke begrippen
| Begrip | Betekenis |
|---|---|
| Model | De codedefinitie van een tabel en de velden. |
| Schema | De volledige beschrijving van alle tabellen, velden en relaties. |
| Relatie | Een verbinding tussen modellen, zoals een boeking die bij een klant hoort. |
| Migratie | Een geversioneerd script dat de databasestructuur verandert. |
| Query builder | Een lichter hulpmiddel om SQL in code op te bouwen zonder volledige objectkoppeling. |
| N+1-probleem | Eén query voor een lijst uitvoeren en dan nog één per item — traag bij grote aantallen. |
| Ruwe SQL | Handgeschreven SQL, gebruikt wanneer de ORM in de weg zit. |
Veelvoorkomende misverstanden
- ‘Een ORM is een database.’ Dat klopt niet. Het is een vertaler. Je hebt nog steeds een database nodig, zoals Postgres.
- ‘Met een ORM hoef je je gegevens niet te begrijpen.’ Slecht ontworpen tabellen zijn ook via een ORM pijnlijk. Een goed datamodel is belangrijker dan het gereedschap.
- ‘ORM's zijn altijd traag.’ Dagelijkse query's zijn prima. Vertraging komt meestal door patronen zoals N+1-query's of ontbrekende indexen, en die zijn op te lossen.
- ‘Een ORM betekent nooit een risico op SQL-injectie.’ Standaardmethoden van ORM's zijn veilig, maar ruwe SQL met ingeplakte invoer van gebruikers blijft gevaarlijk.
- ‘Het bewerken van het schemabestand verandert de live database.’ Pas wanneer een migratie is gemaakt en op die database is toegepast.
Wat je aan je AI-appbouwer kunt vragen
- ‘Laat me het databaseschema zien en leg elke tabel en relatie in gewone taal uit.’
- ‘Welke ORM gebruikt dit project en waar staan de migraties?’
- ‘Vertel me voordat je een tabel wijzigt of bestaande gegevens daardoor geraakt worden, en verwijder nooit een kolom met gegevens zonder het eerst te vragen.’
- ‘Controleer de traagste pagina’s op N+1-query’s en voeg indexen toe waar lijsten worden gefilterd of gesorteerd.’
- ‘Zorg dat elke query met invoer van gebruikers via de ORM of met parameters loopt — geen SQL die aan elkaar wordt geplakt.’
ORM's in Mythex
Als je app gegevens moet opslaan, voegt Mythex een eigen Postgres-database toe aan het project — vraag het in de chat of gebruik het commando /database — en zet het de verbindingsgegevens in de werkruimte en de gepubliceerde app (Database). De agent schrijft vervolgens de code die je gegevens leest en opslaat. Heb je een voorkeur — ‘gebruik Prisma’, ‘gebruik SQLAlchemy’ of ‘gewone SQL, geen ORM’ — zeg dat dan in de chat. Vraag de agent het schema toe te lichten wanneer je de structuur wilt controleren; de bestanden kun je in de codeeditor lezen. Voor het grotere plaatje, zie wat is een database en SQL vs NoSQL.
Veelgestelde vragen
Wat is een ORM in simpele termen?
Een ORM (object-relational mapper) is een codebibliotheek die tussen je app en een relationele database zit. Het laat ontwikkelaars gegevens lezen en opslaan als gewone objecten in hun programmeertaal, en schrijft achter de schermen de SQL-query's voor hen.
Wat zijn voorbeelden van ORM's?
Veelgebruikte ORM's zijn Prisma en Drizzle voor TypeScript en JavaScript, SQLAlchemy en de Django ORM voor Python, Entity Framework Core voor C#, Hibernate voor Java en Active Record in Ruby on Rails.
Is een ORM beter dan zelf SQL schrijven?
Dat hangt af van de taak. Een ORM maakt dagelijkse lees- en schrijfacties sneller te schrijven, veiliger en makkelijker aan te passen, terwijl handgeschreven SQL volledige controle geeft voor complexe rapporten of query's waarbij prestaties cruciaal zijn. De meeste ORM's laten je bij nood terugvallen op ruwe SQL.
Wat is een migratie?
Een migratie is een klein, geversioneerd script dat de structuur van de database verandert, zoals het toevoegen van een tabel of kolom. ORM's kunnen migraties genereren uit je datamodel, zodat elke kopie van de database — op een laptop, in tests en in productie — dezelfde structuur krijgt.