ORM (Objektrelationales Mapping) ist eine Technik, die die Lücke zwischen objektorientierter Programmierung und relationalen Datenbanken schließt. Klassen werden auf Tabellen abgebildet, Objekte auf Zeilen und Attribute auf Spalten – so arbeiten Entwickler mit vertrauten Objekten, statt SQL-Strings zu schreiben.

Das Problem: Impedance Mismatch

Relationale Datenbanken speichern Daten in Tabellen mit Zeilen und Spalten; moderne Sprachen arbeiten mit Objekten, Vererbung und Sammlungen. Diese unterschiedlichen Modelle werden Impedance Mismatch genannt. ORM übersetzt zwischen beiden Welten und spart dadurch viel Boilerplate-Code.

Wie ORM funktioniert

Ein ORM-Framework bindet zur Laufzeit Klassen an Tabellen (Mapping). Beim Speichern erzeugt es automatisch INSERT/UPDATE, beim Laden baut es Objekte aus SELECT-Ergebnissen. Beziehungen wie 1:n oder n:m werden über Fremdschlüssel abgebildet (siehe Primär- und Fremdschlüssel) – das ORM erzeugt daraus die passenden JOINs (siehe SQL: JOINs richtig verstehen).

Vorteile

  • Weniger Code: CRUD-Operationen ohne manuelle SQL-Statements
  • Typsicherheit: Fehler werden oft schon beim Kompilieren erkannt
  • Portabilität: Das ORM erzeugt Dialekt-spezifisches SQL für verschiedene Datenbanken
  • Sicherheit: Parameterisierung verhindert SQL-Injection

Nachteile und Fallstricke

  • N+1-Problem: Beim Laden einer Liste mit Beziehungen erzeugt naives ORM pro Zeile eine zusätzliche Query – Abhilfe: Eager Loading oder Joins
  • Lazy Loading: verzögerter Zugriff kann zu unerwarteten Queries führen
  • Komplexe Abfragen: schwierige Queries sind in reinem SQL oft lesbarer und schneller
  • Performance-Overhead: das generierte SQL ist nicht immer optimal – dann greift man gezielt zu rohem SQL oder Views

Bekannte ORM-Frameworks

SpracheORM
JavaHibernate, JPA
C#/.NETEntity Framework Core
PythonSQLAlchemy, Django ORM
PHPDoctrine, Eloquent (Laravel)
RubyActiveRecord (Rails)
JavaScript/TypeScriptSequelize, Prisma, Drizzle
GoGORM, ent
RustDiesel

Beispiel mit Python/SQLAlchemy

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker

engine = create_engine("postgresql://user:pass@localhost/firmendb")
Base = declarative_base()

class Kunde(Base):
    __tablename__ = "kunden"
    id = Column(Integer, primary_key=True)
    name = Column(String)

session = sessionmaker(engine)()
neuer_kunde = Kunde(name="Hanse Computing")
session.add(neuer_kunde)
session.commit()

Damit die Datenbank hinter dem ORM sauber bleibt, spielen ein durchdachtes Datenbankschema und Normalisierung eine zentrale Rolle. Auch Indizes sind wichtig, damit die vom ORM erzeugten Queries schnell bleiben.