Skip to content

Commit 80f0065

Browse files
committed
chore: add orm
1 parent 0a34af9 commit 80f0065

19 files changed

+1455
-0
lines changed

docs/9_orm/0_intro.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Object-Relational Mapping (ORM)
2+
3+
Die meisten modernen Anwendungen sind objektorientiert aufgebaut, während die Daten in relationalen Datenbanken gespeichert werden. Diese grundlegende Diskrepanz zwischen objektorientierter Programmierung und relationalen Datenbanken - bekannt als "Object-Relational Impedance Mismatch" - stellt Entwickler vor eine besondere Herausforderung: Wie überbrückt man die konzeptionelle Lücke zwischen Objekten in der Anwendung und Tabellen in der Datenbank effizient?
4+
5+
Object-Relational Mapping (ORM) ist die Antwort auf diese Herausforderung. ORMs bieten eine Abstraktionsschicht zwischen dem Anwendungscode und der relationalen Datenbank, die es ermöglicht, mit Daten in Form von Objekten zu arbeiten, anstatt SQL-Abfragen manuell zu schreiben.
6+
7+
:::{important} Lernziele
8+
Nach Abschluss dieses Kapitels wirst du:
9+
- Das Konzept und die Grundprinzipien von Object-Relational Mapping verstehen
10+
- Die Vor- und Nachteile von ORMs im Vergleich zu direktem SQL-Zugriff beurteilen können
11+
- Grundlegende Mapping-Strategien zwischen Objekten und Datenbanktabellen kennen
12+
- Die Rolle von ORM-Frameworks in modernen Anwendungen einordnen können
13+
- Die Bedeutung von Schemaversionierung in datenbankbasierten Anwendungen erfassen
14+
- Wissen, wann ORMs an ihre Grenzen stossen und direktes SQL die bessere Wahl ist
15+
:::
16+
17+
## Warum sind ORMs für Entwickler relevant?
18+
19+
Als Softwareentwickler stehst du häufig vor der Herausforderung, deine objektorientierten Anwendungen mit relationalen Datenbanken zu verbinden. Ohne geeignete Abstraktionen müsstest du:
20+
21+
- SQL-Abfragen manuell schreiben und in deinen Code einbetten
22+
- Die Ergebnisse dieser Abfragen selbst in Objekte umwandeln
23+
- Änderungen an Objekten zurück in SQL-UPDATE-Anweisungen transformieren
24+
- Beziehungen zwischen Objekten manuell durch JOINs oder mehrere Abfragen abbilden
25+
26+
Dieser Ansatz ist fehleranfällig und erhöht den Wartungsaufwand erheblich. Jede Änderung am Datenbankschema erfordert entsprechende Anpassungen im Code, und das Management komplexer Beziehungen zwischen Objekten wird schnell unübersichtlich.
27+
28+
Object-Relational Mapper lösen diese Probleme, indem sie eine strukturierte Brücke zwischen der objektorientierten und der relationalen Welt schaffen. Sie ermöglichen es dir, dich auf die Geschäftslogik deiner Anwendung zu konzentrieren, während sich das ORM um die Datenpersistenz kümmert.
29+
30+
In diesem Kapitel werden wir die grundlegenden Konzepte und Prinzipien von ORMs betrachten und anhand von repräsentativen Beispielen aus Java und Python veranschaulichen. Du wirst lernen, wann der Einsatz eines ORMs sinnvoll ist und wann du besser auf direktes SQL zurückgreifen solltest.
31+
32+
Besonders wichtig wird dabei die Betrachtung der Schemaversionierung sein - ein oft übersehener, aber kritischer Aspekt in der professionellen Softwareentwicklung mit Datenbanken. Wir werden erklären, warum eine kontrollierte Verwaltung von Datenbankschemas in professionellen Umgebungen dem automatischen Schema-Management durch ORMs vorzuziehen ist.

docs/9_orm/1_orm_basics.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# Grundlagen des Object-Relational Mappings
2+
3+
Object-Relational Mapping (ORM) ist ein Programmierparadigma, das die Lücke zwischen objektorientierter Programmierung und relationalen Datenbanken überbrückt. In diesem Kapitel betrachten wir die grundlegenden Konzepte und Mechanismen, die ORMs verwenden, um eine nahtlose Integration zwischen diesen beiden Welten zu ermöglichen.
4+
5+
## Die konzeptionelle Herausforderung
6+
7+
```mermaid
8+
flowchart LR
9+
subgraph "Objektorientierte Welt"
10+
A[Klassen] --- B[Vererbung]
11+
B --- C[Polymorphismus]
12+
A --- D[Objekte mit Methoden]
13+
D --- E[Objektreferenzen]
14+
end
15+
16+
subgraph "Relationale Welt"
17+
F[Tabellen] --- G[Spalten/Datentypen]
18+
G --- H[Constraints]
19+
F --- I[Zeilen mit Werten]
20+
I --- J[Fremdschlüssel]
21+
end
22+
23+
K[ORM] --- A
24+
K --- F
25+
```
26+
27+
Die obige Abbildung veranschaulicht den fundamentalen Unterschied zwischen objektorientierter Programmierung und relationalen Datenbanken. Objektorientierte Programmierung basiert auf Klassen, Vererbung und Objektreferenzen, während relationale Datenbanken auf Tabellen, Zeilen und Fremdschlüsselbeziehungen aufbauen. Diese unterschiedlichen Paradigmen führen zu mehreren Herausforderungen:
28+
29+
1. **Strukturelle Unterschiede**: Objekte können komplexe Vererbungshierarchien haben, während Tabellen flach strukturiert sind.
30+
2. **Identitätskonzepte**: In der objektorientierten Welt hat jedes Objekt eine eigene Identität, während in relationalen Datenbanken die Identität durch Primärschlüssel definiert wird.
31+
3. **Beziehungsdarstellung**: Objekte verwenden Referenzen für Beziehungen, relationale Datenbanken nutzen Fremdschlüssel und JOINs.
32+
4. **Datentypen**: Programmiersprachen und Datenbanken haben unterschiedliche Typsysteme.
33+
5. **Verhalten**: Objekte beinhalten sowohl Daten als auch Verhalten (Methoden), während Tabellen nur Daten speichern.
34+
35+
ORMs versuchen, diese Unterschiede zu überbrücken und eine konsistente Programmierumgebung zu schaffen, in der Entwickler hauptsächlich mit Objekten arbeiten können.
36+
37+
## Kernkomponenten eines ORM-Systems
38+
39+
Ein typisches ORM-System besteht aus mehreren Schlüsselkomponenten:
40+
41+
### 1. Entity-Mapping
42+
43+
Das Entity-Mapping bildet Klassen auf Datenbanktabellen ab. In den meisten ORM-Frameworks geschieht dies durch Annotationen oder Konfigurationsdateien.
44+
45+
**Beispiel für Entity-Mapping:**
46+
47+
```java
48+
// Java mit JPA
49+
@Entity
50+
@Table(name = "mitglieder")
51+
public class Mitglied {
52+
@Id
53+
private Long id;
54+
55+
@Column(name = "nachname")
56+
private String nachname;
57+
58+
// Weitere Eigenschaften...
59+
}
60+
```
61+
62+
```python
63+
# Python mit SQLAlchemy
64+
class Mitglied(Base):
65+
__tablename__ = 'mitglieder'
66+
67+
id = Column(Integer, primary_key=True)
68+
nachname = Column(String)
69+
# Weitere Eigenschaften...
70+
```
71+
72+
### 2. Beziehungs-Mapping
73+
74+
ORMs bieten Mechanismen, um verschiedene Arten von Beziehungen zwischen Entitäten abzubilden:
75+
76+
**Beispiele für Beziehungs-Mapping:**
77+
78+
```java
79+
// Java: One-to-Many Beziehung
80+
@Entity
81+
public class Verein {
82+
// ...
83+
@OneToMany(mappedBy = "verein")
84+
private List<Mitglied> mitglieder;
85+
}
86+
87+
@Entity
88+
public class Mitglied {
89+
// ...
90+
@ManyToOne
91+
@JoinColumn(name = "verein_id")
92+
private Verein verein;
93+
}
94+
```
95+
96+
```python
97+
# Python: Many-to-Many Beziehung
98+
mitglied_veranstaltung = Table(
99+
'mitglied_veranstaltung',
100+
Base.metadata,
101+
Column('mitglied_id', Integer, ForeignKey('mitglieder.id')),
102+
Column('veranstaltung_id', Integer, ForeignKey('veranstaltungen.id'))
103+
)
104+
105+
class Mitglied(Base):
106+
# ...
107+
veranstaltungen = relationship("Veranstaltung", secondary=mitglied_veranstaltung)
108+
```
109+
110+
### 3. Object-Relational-Mapping-Lebenszyklus
111+
112+
ORMs verwalten den Lebenszyklus von Entitäten durch verschiedene Zustände:
113+
114+
```mermaid
115+
stateDiagram-v2
116+
[*] --> Transient: Neues Objekt erstellt
117+
Transient --> Persistent: persist()/save()
118+
Persistent --> Detached: close()/clear()
119+
Detached --> Persistent: merge()/update()
120+
Persistent --> Removed: remove()/delete()
121+
Removed --> [*]
122+
Detached --> [*]: Garbage Collection
123+
```
124+
125+
1. **Transient**: Ein neues Objekt, das nicht mit einer Datenbankzeile verbunden ist
126+
2. **Persistent**: Ein Objekt, das einer Datenbankzeile zugeordnet ist und vom ORM verwaltet wird
127+
3. **Detached**: Ein Objekt, das einer Datenbankzeile zugeordnet war, aber nicht mehr vom ORM verwaltet wird
128+
4. **Removed**: Ein Objekt, das zum Löschen markiert wurde
129+
130+
### 4. Lazy Loading vs. Eager Loading
131+
132+
Ein wichtiges Konzept in ORMs ist die Ladestrategie für Beziehungen:
133+
134+
- **Lazy Loading**: Beziehungen werden erst geladen, wenn explizit auf sie zugegriffen wird
135+
```java
136+
// Lazy Loading (Standard in den meisten ORM-Frameworks)
137+
@OneToMany(mappedBy = "verein", fetch = FetchType.LAZY)
138+
private List<Mitglied> mitglieder;
139+
```
140+
141+
- **Eager Loading**: Beziehungen werden sofort geladen, wenn das Hauptobjekt geladen wird
142+
143+
Die Wahl der richtigen Ladestrategie ist entscheidend für die Performance der Anwendung. Lazy Loading reduziert den initialen Ladeaufwand, kann aber zu dem "N+1-Problem" führen, wenn in einer Schleife auf viele beziehungsgebundene Objekte zugegriffen wird.
144+
145+
## Abfragesprachen von ORMs
146+
147+
ORMs bieten in der Regel eigene Abfragesprachen, die objektorientierten Zugriff auf die Datenbank ermöglichen:
148+
149+
Die ORMs bieten verschiedene Abfragesprachen, die objektorientiert sind und eine Alternative zu direktem SQL darstellen:
150+
151+
```java
152+
// JPQL in Java
153+
TypedQuery<Mitglied> query = entityManager.createQuery(
154+
"SELECT m FROM Mitglied m WHERE m.nachname = :nachname", Mitglied.class);
155+
query.setParameter("nachname", "Müller");
156+
List<Mitglied> results = query.getResultList();
157+
```
158+
159+
```python
160+
# Method Chaining in SQLAlchemy
161+
session.query(Mitglied).filter(Mitglied.nachname == "Müller").all()
162+
```
163+
164+
Diese spezifischen Abfragesprachen ermöglichen es, komplexe Datenbankoperationen in einer objektorientierten Weise auszudrücken, die sich natürlicher in den Programmcode einfügt.
165+
166+
## Fazit
167+
168+
Die Grundlagen des Object-Relational Mappings umfassen Entity-Mapping, Beziehungs-Mapping, den Entitäts-Lebenszyklus und spezielle Abfragesprachen. Diese Konzepte bilden das Fundament für den effizienten Einsatz von ORMs in Anwendungen.
169+
170+
Im nächsten Kapitel werden wir die Vor- und Nachteile von ORMs genauer betrachten und diskutieren, wann ihr Einsatz sinnvoll ist und wann möglicherweise direktes SQL die bessere Alternative darstellt.

0 commit comments

Comments
 (0)