Eins-zu-eins-Beziehungen
Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →
Eine Eins-zu-eins-Beziehung liegt vor, wenn A genau eine Instanz von B enthält und B genau eine Instanz von A.
Nehmen wir beispielsweise die Entitäten User und Profile.
Ein Benutzer kann nur ein einzelnes Profil haben, und ein Profil gehört immer genau einem Benutzer.
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number
@Column()
gender: string
@Column()
photo: string
}
import {
Entity,
PrimaryGeneratedColumn,
Column,
OneToOne,
JoinColumn,
} from "typeorm"
import { Profile } from "./Profile"
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@OneToOne(() => Profile)
@JoinColumn()
profile: Profile
}
Hier haben wir @OneToOne zum user hinzugefügt und den Zielbeziehungstyp als Profile festgelegt.
Zusätzlich haben wir @JoinColumn hinzugefügt, das erforderlich ist und nur auf einer Seite der Beziehung gesetzt werden muss.
Auf der Seite, wo @JoinColumn gesetzt ist, enthält die Tabelle eine "Relation ID" und Fremdschlüssel zur Zieltabelle.
Dieses Beispiel erzeugt folgende Tabellen:
+-------------+--------------+----------------------------+
| profile |
+-------------+--------------+----------------------------+
| id | int | PRIMARY KEY AUTO_INCREMENT |
| gender | varchar(255) | |
| photo | varchar(255) | |
+-------------+--------------+----------------------------+
+-------------+--------------+----------------------------+
| user |
+-------------+--------------+----------------------------+
| id | int | PRIMARY KEY AUTO_INCREMENT |
| name | varchar(255) | |
| profileId | int | FOREIGN KEY |
+-------------+--------------+----------------------------+
Nochmals: @JoinColumn darf nur auf einer Seite der Beziehung stehen – jener, die den Fremdschlüssel in der Datenbanktabelle haben muss.
Beispiel zum Speichern einer solchen Beziehung:
const profile = new Profile()
profile.gender = "male"
profile.photo = "me.jpg"
await dataSource.manager.save(profile)
const user = new User()
user.name = "Joe Smith"
user.profile = profile
await dataSource.manager.save(user)
Mit aktivierten Cascades können Sie diese Beziehung mit nur einem save-Aufruf speichern.
Um einen Benutzer mit Profil zu laden, müssen Sie die Beziehung in FindOptions angeben:
const users = await dataSource.getRepository(User).find({
relations: {
profile: true,
},
})
Oder mit QueryBuilder können Sie sie verknüpfen:
const users = await dataSource
.getRepository(User)
.createQueryBuilder("user")
.leftJoinAndSelect("user.profile", "profile")
.getMany()
Wenn Eager Loading für eine Beziehung aktiviert ist, müssen Sie sie nicht in find-Befehlen angeben – sie wird IMMER automatisch geladen. Bei QueryBuilder ist Eager Loading deaktiviert; Sie müssen leftJoinAndSelect verwenden.
Beziehungen können unidirektional oder bidirektional sein. Unidirektional bedeutet: Relations-Decorator nur auf einer Seite. Bidirektional bedeutet: Decorators auf beiden Seiten der Beziehung.
Wir haben bisher eine unidirektionale Beziehung. Machen wir sie bidirektional:
import { Entity, PrimaryGeneratedColumn, Column, OneToOne } from "typeorm"
import { User } from "./User"
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number
@Column()
gender: string
@Column()
photo: string
@OneToOne(() => User, (user) => user.profile) // specify inverse side as a second parameter
user: User
}
import {
Entity,
PrimaryGeneratedColumn,
Column,
OneToOne,
JoinColumn,
} from "typeorm"
import { Profile } from "./Profile"
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@OneToOne(() => Profile, (profile) => profile.user) // specify inverse side as a second parameter
@JoinColumn()
profile: Profile
}
Jetzt ist unsere Beziehung bidirektional. Beachten Sie: Die inverse Beziehung hat kein @JoinColumn.
@JoinColumn darf nur auf einer Seite stehen – der Tabelle, die den Fremdschlüssel besitzt.
Bidirektionale Beziehungen ermöglichen das Verknüpfen von beiden Seiten mit QueryBuilder:
const profiles = await dataSource
.getRepository(Profile)
.createQueryBuilder("profile")
.leftJoinAndSelect("profile.user", "user")
.getMany()