fontcolor_theme
Deepkit ORM

Relationen

Beziehungen ermöglichen es, zwei Entities auf bestimmte Weise zu verbinden. Dies geschieht in Datenbanken üblicherweise mithilfe des Konzepts der Foreign Keys. Deepkit ORM unterstützt Relationen für alle offiziellen Database Adapter.

Eine Relation wird mit dem Reference Decorator annotiert. Üblicherweise hat eine Relation auch eine umgekehrte Relation, die mit dem BackReference Type annotiert wird, aber nur benötigt wird, wenn die umgekehrte Relation in einer Database Query verwendet werden soll. Back References sind nur virtuell.

Eins-zu-Viele

Die Entity, die eine Referenz speichert, wird üblicherweise als die owning side bzw. diejenige bezeichnet, die die Referenz owns. Der folgende Code zeigt zwei Entities mit einer Eins-zu-Viele-Beziehung zwischen User und Post. Das bedeutet, dass ein User mehrere Post haben kann. Die post-Entity hat die Relation post->user. In der Datenbank selbst gibt es nun ein Feld Post. "author", das den Primary Key von User enthält.

import { SQLiteDatabaseAdapter } from '@deepkit/sqlite';
import { entity, PrimaryKey, AutoIncrement, 
    Reference } from '@deepkit/type';
import { Database } from '@deepkit/orm';

@entity.collection('users')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    constructor(public username: string) {
    }
}

@entity.collection('posts')
class Post {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    constructor(
        public author: User & Reference,
        public title: string
    ) {
    }
}

const database = new Database(
    new SQLiteDatabaseAdapter(':memory:'), 
    [User, Post]
);
await database.migrate();

const user1 = new User('User1');
const post1 = new Post(user1, 'My first blog post');
const post2 = new Post(user1, 'My second blog post');

await database.persist(user1, post1, post2);

Referenzen werden in Queries standardmäßig nicht ausgewählt. Siehe Datenbank-Joins für Details.

Viele-zu-Eins

Eine Referenz hat üblicherweise eine umgekehrte Referenz (Viele-zu-Eins). Sie ist nur eine virtuelle Referenz, da sie sich nicht in der Datenbank selbst widerspiegelt. Eine Back Reference wird mit BackReference annotiert und wird hauptsächlich für Reflection und Query Joins verwendet. Wenn Sie eine BackReference von User zu Post hinzufügen, können Sie Post direkt aus User-Queries joinen.

@entity.name('user').collection('users')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    posts?: Post[] & BackReference;

    constructor(public username: string) {
    }
}
//[ { username: 'User1', posts: [ [Post], [Post] ] } ]
const users = await database.query(User)
    .select('username', 'posts')
    .joinWith('posts')
    .find();

Viele-zu-Viele

Eine Viele-zu-Viele-Beziehung ermöglicht es, viele Datensätze mit vielen anderen zu verknüpfen. Sie kann beispielsweise für Users in Groups verwendet werden. Ein User kann in keiner, einer oder vielen Groups sein. Folglich kann eine Group 0, eine oder viele Users enthalten.

Viele-zu-Viele-Beziehungen werden üblicherweise mithilfe einer Pivot-Entity implementiert. Die Pivot-Entity enthält die tatsächlichen eigenen Referenzen zu zwei anderen Entities, und diese beiden Entities haben Back References zur Pivot-Entity.

@entity.name('user')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    groups?: Group[] & BackReference<{via: typeof UserGroup}>;

    constructor(public username: string) {
    }
}

@entity.name('group')
class Group {
    id: number & PrimaryKey & AutoIncrement = 0;

    users?: User[] & BackReference<{via: typeof UserGroup}>;

    constructor(public name: string) {
    }
}

//die Pivot-Entity
@entity.name('userGroup')
class UserGroup {
    id: number & PrimaryKey & AutoIncrement = 0;

    constructor(
        public user: User & Reference,
        public group: Group & Reference,
    ) {
    }
}

Mit diesen Entities können Sie nun Users und Groups erstellen und sie über die Pivot-Entity miteinander verbinden. Durch die Verwendung einer Back Reference in User können wir die Groups direkt mit einer User-Query abrufen.

const database = new Database(new SQLiteDatabaseAdapter(':memory:'), [User, Group, UserGroup]);
await database.migrate();

const user1 = new User('User1');
const user2 = new User('User2');
const group1 = new Group('Group1');

await database.persist(user1, user2, group1, new UserGroup(user1, group1), new UserGroup(user2, group1));

//[
//   { id: 1, username: 'User1', groups: [ [Group] ] },
//   { id: 2, username: 'User2', groups: [ [Group] ] }
// ]
const users = await database.query(User)
    .select('username', 'groups')
    .joinWith('groups')
    .find();

Um die Verknüpfung eines Users mit einer Group aufzuheben, wird der UserGroup-Datensatz gelöscht:

const users = await database.query(UserGroup)
    .filter({user: user1, group: group1})
    .deleteOne();

Eins-zu-Eins

Constraints

Bei Delete/Update: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

English中文 (Chinese)한국어 (Korean)日本語 (Japanese)Deutsch (German)