Entitäten
Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →
Was ist eine Entität?
Eine Entität ist eine Klasse, die auf eine Datenbanktabelle (oder bei MongoDB auf eine Sammlung) abgebildet wird.
Sie können eine Entität erstellen, indem Sie eine neue Klasse definieren und sie mit @Entity() markieren:
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
firstName: string
@Column()
lastName: string
@Column()
isActive: boolean
}
Dadurch wird folgende Datenbanktabelle erstellt:
+-------------+--------------+----------------------------+
| user |
+-------------+--------------+----------------------------+
| id | int | PRIMARY KEY AUTO_INCREMENT |
| firstName | varchar(255) | |
| lastName | varchar(255) | |
| isActive | boolean | |
+-------------+--------------+----------------------------+
Grundlegende Entitäten bestehen aus Spalten und Beziehungen. Jede Entität MUSS eine Primärspalte haben (oder eine ObjectId-Spalte bei Verwendung von MongoDB).
Jede Entität muss in Ihren Data-Source-Optionen registriert werden:
import { DataSource } from "typeorm"
import { User } from "./entities/User"
const myDataSource = new DataSource({
type: "mysql",
host: "localhost",
port: 3306,
username: "test",
password: "test",
database: "test",
entities: [User],
})
Alternativ können Sie das gesamte Verzeichnis mit allen Entitäten angeben – diese werden dann automatisch geladen:
import { DataSource } from "typeorm"
const dataSource = new DataSource({
type: "mysql",
host: "localhost",
port: 3306,
username: "test",
password: "test",
database: "test",
entities: [__dirname + "/entities/**/*{.js,.ts}"],
})
Falls Sie einen alternativen Tabellennamen für die User-Entität verwenden möchten, können Sie dies in @Entity angeben: @Entity("my_users").
Wenn Sie einen Basispräfix für alle Datenbanktabellen Ihrer Anwendung setzen möchten, können Sie entityPrefix in den Data-Source-Optionen festlegen.
Bei Verwendung eines Entitätskonstruktors müssen dessen Argumente optional sein. Da der ORM beim Laden aus der Datenbank Instanzen von Entitätsklassen erstellt, kennt er Ihre Konstruktorargumente nicht.
Weitere Informationen zu Parametern von @Entity finden Sie in der Dekoratoren-Referenz.
Entitätsspalten
Da Datenbanktabellen aus Spalten bestehen, müssen auch Ihre Entitäten Spalten enthalten.
Jede Eigenschaft einer Entitätsklasse, die Sie mit @Column markieren, wird auf eine Spalte in der Datenbanktabelle abgebildet.
Primärspalten
Jede Entität muss mindestens eine Primärspalte haben. Es gibt verschiedene Arten von Primärspalten:
@PrimaryColumn()erstellt eine Primärspalte, die beliebige Werte jedes Typs akzeptiert. Sie können den Spaltentyp festlegen. Ohne Angabe wird der Typ automatisch vom Eigenschaftstyp abgeleitet. Im Beispiel unten entsteht eine id-Spalte vom Typint, deren Wert Sie vor dem Speichern manuell zuweisen müssen.
import { Entity, PrimaryColumn } from "typeorm"
@Entity()
export class User {
@PrimaryColumn()
id: number
}
@PrimaryGeneratedColumn()erstellt eine Primärspalte, deren Wert automatisch durch Auto-Inkrement generiert wird. Es entsteht eineint-Spalte mitauto-increment/serial/sequence/identity(abhängig von Datenbank und Konfiguration). Sie müssen den Wert nicht manuell vor dem Speichern zuweisen – er wird automatisch generiert.
import { Entity, PrimaryGeneratedColumn } from "typeorm"
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
}
@PrimaryGeneratedColumn("uuid")erstellt eine Primärspalte, deren Wert automatisch alsuuidgeneriert wird. Uuid ist ein eindeutiger String-Identifier. Sie müssen den Wert nicht manuell zuweisen – er wird automatisch generiert.
import { Entity, PrimaryGeneratedColumn } from "typeorm"
@Entity()
export class User {
@PrimaryGeneratedColumn("uuid")
id: string
}
Sie können auch zusammengesetzte Primärspalten verwenden:
import { Entity, PrimaryColumn } from "typeorm"
@Entity()
export class User {
@PrimaryColumn()
firstName: string
@PrimaryColumn()
lastName: string
}
Beim Speichern von Entitäten mit save wird stets versucht, eine Entität mit der angegebenen ID (oder IDs) in der Datenbank zu finden.
Wenn die ID/IDs gefunden werden, wird die entsprechende Zeile aktualisiert.
Wenn keine Zeile mit der ID/IDs existiert, wird eine neue Zeile eingefügt.
Um eine Entität anhand ihrer ID zu finden, können Sie manager.findOneBy oder repository.findOneBy verwenden. Beispiel:
// find one by id with single primary key
const person = await dataSource.manager.findOneBy(Person, { id: 1 })
const person = await dataSource.getRepository(Person).findOneBy({ id: 1 })
// find one by id with composite primary keys
const user = await dataSource.manager.findOneBy(User, {
firstName: "Timber",
lastName: "Saw",
})
const user = await dataSource.getRepository(User).findOneBy({
firstName: "Timber",
lastName: "Saw",
})
Spezielle Spalten
Es stehen mehrere spezielle Spaltentypen mit Zusatzfunktionen zur Verfügung:
-
@CreateDateColumnist eine spezielle Spalte, die automatisch auf das Erstellungsdatum der Entität gesetzt wird. Sie müssen diese Spalte nicht setzen – sie wird automatisch befüllt. -
@UpdateDateColumnist eine spezielle Spalte, die bei jedem Aufruf vonsave(Entity Manager/Repository) oder währendupsert-Operationen bei Updates automatisch auf den Zeitpunkt der Aktualisierung gesetzt wird. Sie müssen diese Spalte nicht setzen – sie wird automatisch befüllt. -
@DeleteDateColumnist eine spezielle Spalte, die bei Soft-Delete-Operationen automatisch auf den Löschzeitpunkt gesetzt wird. Sie müssen diese Spalte nicht setzen – sie wird automatisch befüllt. Ist @DeleteDateColumn gesetzt, gilt standardmäßig der Scope "nicht gelöscht". -
@VersionColumnist eine spezielle Spalte, die bei jedemsave-Aufruf oder währendupsert-Updates automatisch auf die aktuelle Versionsnummer (fortlaufende Zahl) der Entität gesetzt wird. Sie müssen diese Spalte nicht setzen – sie wird automatisch befüllt.
Spaltentypen
TypeORM unterstützt alle gängigsten datenbankbasierten Spaltentypen. Spaltentypen sind datenbankspezifisch – dies ermöglicht mehr Flexibilität beim Design Ihres Datenbankschemas.
Sie können den Spaltentyp als ersten Parameter von @Column angeben
oder in den Spaltenoptionen von @Column, zum Beispiel:
@Column("int")
oder
@Column({ type: "int" })
Wenn Sie zusätzliche Typparameter angeben möchten, können Sie dies über die Spaltenoptionen tun. Beispiel:
@Column("varchar", { length: 200 })
Hinweis zum Typ
bigint: Derbigint-Spaltentyp in SQL-Datenbanken passt nicht in den regulärennumber-Typ und mappt die Eigenschaft stattdessen auf einenstring.
enum-Spaltentyp
Der enum-Spaltentyp wird von postgres und mysql unterstützt. Es gibt verschiedene Definitionsmöglichkeiten:
Verwendung von TypeScript-Enums:
export enum UserRole {
ADMIN = "admin",
EDITOR = "editor",
GHOST = "ghost",
}
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column({
type: "enum",
enum: UserRole,
default: UserRole.GHOST,
})
role: UserRole
}
Hinweis: String-, numerische und heterogene Enums werden unterstützt.
Verwendung eines Arrays mit Enum-Werten:
export type UserRoleType = "admin" | "editor" | "ghost",
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({
type: "enum",
enum: ["admin", "editor", "ghost"],
default: "ghost"
})
role: UserRoleType
}
simple-array-Spaltentyp
Es gibt einen speziellen Spaltentyp simple-array, der primitive Array-Werte in einer einzelnen String-Spalte speichert.
Alle Werte sind durch Kommas getrennt. Beispiel:
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column("simple-array")
names: string[]
}
const user = new User()
user.names = ["Alexander", "Alex", "Sasha", "Shurik"]
Wird in einer einzelnen Datenbankspalte als Wert Alexander,Alex,Sasha,Shurik gespeichert.
Beim Laden der Daten aus der Datenbank werden die Namen als Array zurückgegeben,
genau wie sie gespeichert wurden.
Wichtig: Werte dürfen KEINE Kommas enthalten.
simple-json-Spaltentyp
Der spezielle Spaltentyp simple-json kann beliebige Werte speichern, die via JSON.stringify
in der Datenbank gespeichert werden können.
Besonders nützlich, wenn Ihr Datenbanksystem keinen JSON-Typ unterstützt und Sie Objekte
ohne Aufwand speichern und laden möchten. Beispiel:
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column("simple-json")
profile: { name: string; nickname: string }
}
const user = new User()
user.profile = { name: "John", nickname: "Malkovich" }
Wird in einer Datenbankspalte als {"name":"John","nickname":"Malkovich"} gespeichert. Beim Laden erhalten Sie Ihr Objekt/Array/Primitiv zurück via JSON.parse.
Spalten mit generierten Werten
Sie können Spalten mit generierten Werten über den Dekorator @Generated erstellen. Beispiel:
@Entity()
export class User {
@PrimaryColumn()
id: number
@Column()
@Generated("uuid")
uuid: string
}
Der uuid-Wert wird automatisch generiert und in der Datenbank gespeichert.
Neben "uuid" gibt es die generierten Typen "increment", "identity" (nur Postgres 10+) und "rowid" (nur CockroachDB), allerdings gelten je nach Datenbankplattform Einschränkungen (z.B. erlauben manche Datenbanken nur eine Inkrement-Spalte oder benötigen sie als Primärschlüssel).
Vektor-Spalten
Vektorspalten werden in MariaDB/MySQL, Microsoft SQL Server, PostgreSQL (über die pgvector-Erweiterung) und SAP HANA Cloud unterstützt. Sie ermöglichen die Speicherung und Abfrage von Vektoreinbettungen für Ähnlichkeitssuchen und Machine-Learning-Anwendungen.
TypeORM unterstützt die Spaltentypen vector und halfvec datenbankübergreifend:
-
vector- Speichert Vektoren als 4-Byte-Floats (einfache Genauigkeit)- MariaDB/MySQL: Nativ
vector-Typ - Microsoft SQL Server: Nativ
vector-Typ - PostgreSQL:
vector-Typ (viapgvector-Erweiterung) - SAP HANA Cloud: Alias für
real_vector-Typ
- MariaDB/MySQL: Nativ
-
halfvec- Speichert Vektoren als 2-Byte-Floats (halbe Genauigkeit) für speichereffiziente Darstellung- PostgreSQL:
halfvec-Typ (viapgvector-Erweiterung) - SAP HANA Cloud: Alias für
half_vector-Typ
- PostgreSQL:
Die Anzahl der Vektordimensionen können Sie mit der length-Option festlegen:
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number
// Vector without specified dimensions
@Column("vector")
embedding: number[] | Buffer
// Vector with 3 dimensions: vector(3)
@Column("vector", { length: 3 })
embedding_3d: number[] | Buffer
// Half-precision vector with 4 dimensions: halfvec(4) (works on PostgreSQL and SAP HANA only)
@Column("halfvec", { length: 4 })
halfvec_embedding: number[] | Buffer
}
Hinweis:
- MariaDB/MySQL: Vektorunterstützung ab MariaDB 11.7 und MySQL 9
- Microsoft SQL Server: Vektortypen erfordern SQL Server 2025 (17.x) oder neuer
- PostgreSQL: Vektorspalten benötigen die
pgvector-Erweiterung (stellt Vektortypen und Ähnlichkeitsoperatoren bereit)- SAP HANA: Vektorspalten erfordern SAP HANA Cloud (2024Q1+) und unterstützte
@sap/hana-client-Version
Räumliche Spalten (Spatial Columns)
Microsoft SQLServer, MySQL/MariaDB, PostgreSQL/CockroachDB und SAP HANA unterstützen räumliche Spalten. TypeORMs Unterstützung variiert je nach Datenbank, insbesondere durch unterschiedliche Spaltennamen.
MS SQL, MySQL/MariaDB und SAP HANA verwenden Geometrien im Well-Known Text (WKT)-Format,
daher sollten Geometriespalten als Typ string markiert werden.
import { Entity, PrimaryColumn, Column } from "typeorm"
@Entity()
export class Thing {
@PrimaryColumn()
id: number
@Column("point")
point: string
@Column("linestring")
linestring: string
}
...
const thing = new Thing()
thing.point = "POINT(1 1)"
thing.linestring = "LINESTRING(0 0,1 1,2 2)"
Für Postgres/CockroachDB siehe PostGIS-Datentypen
Spaltenoptionen
Spaltenoptionen definieren zusätzliche Einstellungen für Ihre Entitätsspalten.
Sie können sie in @Column angeben:
@Column({
type: "varchar",
length: 150,
unique: true,
// ...
})
name: string;
Liste verfügbarer Optionen in ColumnOptions:
-
type: ColumnType- Spaltentyp (einer der oben gelisteten Typen) -
name: string- Spaltenname in der Datenbanktabelle. Standardmäßig wird der Name aus der Eigenschaft abgeleitet. Kann durch eigenen Namen überschrieben werden. -
length: number- Länge des Spaltentyps (z.B. fürvarchar(150)Typangabe + Längenoption) -
onUpdate: string-ON UPDATE-Trigger (nur in MySQL relevant) -
nullable: boolean- LegtNULL/NOT NULL-Constraint fest. Standardwert istnullable: false. -
update: boolean- Gibt an, ob der Spaltenwert durch den "save"-Vorgang aktualisiert wird. Bei false kann der Wert nur beim ersten Einfügen des Objekts geschrieben werden. Standardwert isttrue. -
insert: boolean- Gibt an, ob der Spaltenwert beim ersten Einfügen des Objekts gesetzt wird. Standardwert isttrue. -
select: boolean- Legt fest, ob diese Spalte standardmäßig bei Abfragen ausgeblendet wird. Beifalsewerden die Spaltendaten nicht in einer Standardabfrage angezeigt. Standardmäßig istselect: true. -
default: string- Fügt einenDEFAULT-Wert der Spalte auf Datenbankebene hinzu. -
primary: boolean- Markiert die Spalte als Primärspalte. Entspricht der Verwendung von@PrimaryColumn. -
unique: boolean- Markiert die Spalte als eindeutig (erstellt einen Unique-Constraint). -
comment: string- Kommentar der Spalte in der Datenbank. Nicht von allen Datenbanktypen unterstützt. -
precision: number- Die Genauigkeit für eine Dezimal-Spalte (exakte numerische Spalte, gilt nur für Dezimal-Spalten), also die maximale Anzahl der gespeicherten Ziffern. Wird bei einigen Spaltentypen verwendet. -
scale: number- Die Skalierung für eine Dezimal-Spalte (exakte numerische Spalte, gilt nur für Dezimal-Spalten), die die Anzahl der Nachkommastellen angibt und nicht größer als die Genauigkeit sein darf. Wird bei einigen Spaltentypen verwendet. -
unsigned: boolean- Setzt dasUNSIGNED-Attribut auf eine numerische Spalte. Wird nur in MySQL verwendet. -
charset: string- Definiert den Zeichensatz der Spalte. Nicht von allen Datenbanktypen unterstützt. -
collation: string- Definiert die Sortierreihenfolge (Collation) der Spalte. -
enum: string[]|AnyEnum- Wird beimenum-Spaltentyp verwendet, um die Liste der erlaubten Enum-Werte anzugeben. Sie können ein Array von Werten oder eine Enum-Klasse angeben. -
enumName: string- Definiert den Namen für das verwendete Enum. -
asExpression: string- Ausdruck für eine generierte Spalte. Wird nur in MySQL verwendet. -
generatedType: "VIRTUAL"|"STORED"- Typ der generierten Spalte. Wird nur in MySQL verwendet. -
hstoreType: "object"|"string"- Rückgabetyp derHSTORE-Spalte. Gibt den Wert als String oder Objekt zurück. Wird nur in Postgres verwendet. -
array: boolean- Wird für Postgres- und CockroachDB-Spaltentypen verwendet, die ein Array sein können (z.B. int[]). -
transformer: { from(value: DatabaseType): EntityType, to(value: EntityType): DatabaseType }- Wandelt Eigenschaften des TypsEntityTypein einen datenbankkompatiblen TypDatabaseTypeum. Arrays von Transformatoren werden unterstützt und beim Schreiben in natürlicher Reihenfolge angewendet, beim Lesen in umgekehrter Reihenfolge. Beispiel:[lowercase, encrypt]wandelt den String zuerst in Kleinbuchstaben um und verschlüsselt ihn beim Schreiben; beim Lesen wird entschlüsselt und dann nichts weiter gemacht. -
utc: boolean- Gibt an, ob Datumswerte in UTC-Zeitzone statt der lokalen Zeitzone gespeichert und abgerufen werden sollen. Gilt nur für den Spaltentypdate. Standardwert istfalse(verwendet lokale Zeitzone aus Gründen der Abwärtskompatibilität).
Hinweis: Die meisten dieser Spaltenoptionen sind RDBMS-spezifisch und in MongoDB nicht verfügbar.
Entitätsvererbung
Durch Entitätsvererbung können Sie Redundanzen in Ihrem Code reduzieren.
Beispielsweise haben Sie die Entitäten Photo, Question und Post:
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number
@Column()
title: string
@Column()
description: string
@Column()
size: string
}
@Entity()
export class Question {
@PrimaryGeneratedColumn()
id: number
@Column()
title: string
@Column()
description: string
@Column()
answersCount: number
}
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number
@Column()
title: string
@Column()
description: string
@Column()
viewCount: number
}
Alle diese Entitäten haben gemeinsame Spalten: id, title und description. Um Redundanzen zu reduzieren und eine bessere Abstraktion zu schaffen, können wir eine Basisklasse Content erstellen:
export abstract class Content {
@PrimaryGeneratedColumn()
id: number
@Column()
title: string
@Column()
description: string
}
@Entity()
export class Photo extends Content {
@Column()
size: string
}
@Entity()
export class Question extends Content {
@Column()
answersCount: number
}
@Entity()
export class Post extends Content {
@Column()
viewCount: number
}
Alle Spalten (Relationen, Einbettungen etc.) von übergeordneten Entitäten (die Elternentität kann ebenfalls eine andere Entität erweitern) werden vererbt und in den finalen Entitäten erstellt.
Baumstrukturen in Entitäten
TypeORM unterstützt Adjazenzlisten- und Closure-Tabellen-Muster zur Speicherung von Baumstrukturen.
Adjazenzliste
Eine Adjazenzliste ist ein einfaches Modell mit Selbstreferenzierung.
Vorteil dieses Ansatzes ist die Einfachheit,
Nachteil ist die Unmöglichkeit, große Bäume auf einmal zu laden, bedingt durch JOIN-Beschränkungen.
Beispiel:
import {
Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
OneToMany,
} from "typeorm"
@Entity()
export class Category {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@Column()
description: string
@ManyToOne((type) => Category, (category) => category.children)
parent: Category
@OneToMany((type) => Category, (category) => category.parent)
children: Category[]
}
Closure-Tabelle
Eine Closure-Tabelle speichert Eltern-Kind-Beziehungen auf besondere Weise in einer separaten Tabelle.
Sie ist sowohl beim Lesen als auch Schreiben effizient.
Mehr zu Closure-Tabellen erfahren Sie in dieser hervorragenden Präsentation von Bill Karwin.
Beispiel:
import {
Entity,
Tree,
Column,
PrimaryGeneratedColumn,
TreeChildren,
TreeParent,
TreeLevelColumn,
} from "typeorm"
@Entity()
@Tree("closure-table")
export class Category {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@Column()
description: string
@TreeChildren()
children: Category[]
@TreeParent()
parent: Category
@TreeLevelColumn()
level: number
}