Перейти к основному содержанию

Жадные и ленивые связи

Неофициальный Бета-перевод

Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →

Жадные связи

Жадные связи загружаются автоматически при каждой загрузке сущностей из базы данных. Например:

import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from "typeorm"
import { Question } from "./Question"

@Entity()
export class Category {
@PrimaryGeneratedColumn()
id: number

@Column()
name: string

@ManyToMany((type) => Question, (question) => question.categories)
questions: Question[]
}
import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToMany,
JoinTable,
} from "typeorm"
import { Category } from "./Category"

@Entity()
export class Question {
@PrimaryGeneratedColumn()
id: number

@Column()
title: string

@Column()
text: string

@ManyToMany((type) => Category, (category) => category.questions, {
eager: true,
})
@JoinTable()
categories: Category[]
}

Теперь при загрузке вопросов вам не нужно указывать связи для джоина или загрузки. Они будут загружены автоматически:

const questionRepository = dataSource.getRepository(Question)

// questions will be loaded with its categories
const questions = await questionRepository.find()

Жадные связи работают только при использовании методов find*. При работе с QueryBuilder жадные связи отключаются, и для загрузки связи необходимо использовать leftJoinAndSelect. Жадные связи могут быть активированы только с одной стороны отношения — установка eager: true с обеих сторон запрещена.

Ленивые связи

Сущности в ленивых связях загружаются только при обращении к ним. Такие связи должны иметь тип Promise — вы храните значение в промисах, и при загрузке также возвращается промис. Пример:

import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from "typeorm"
import { Question } from "./Question"

@Entity()
export class Category {
@PrimaryGeneratedColumn()
id: number

@Column()
name: string

@ManyToMany((type) => Question, (question) => question.categories)
questions: Promise<Question[]>
}
import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToMany,
JoinTable,
} from "typeorm"
import { Category } from "./Category"

@Entity()
export class Question {
@PrimaryGeneratedColumn()
id: number

@Column()
title: string

@Column()
text: string

@ManyToMany((type) => Category, (category) => category.questions)
@JoinTable()
categories: Promise<Category[]>
}

categories является Promise. Это означает, что связь ленивая и может хранить только промис с внутренним значением. Пример сохранения такой связи:

const category1 = new Category()
category1.name = "animals"
await dataSource.manager.save(category1)

const category2 = new Category()
category2.name = "zoo"
await dataSource.manager.save(category2)

const question = new Question()
question.categories = Promise.resolve([category1, category2])
await dataSource.manager.save(question)

Пример загрузки объектов внутри ленивых связей:

const [question] = await dataSource.getRepository(Question).find()
const categories = await question.categories
// you'll have all question's categories inside "categories" variable now

Важно: если вы переходите с других языков (Java, PHP и т.д.) и привыкли повсеместно использовать ленивые связи — будьте осторожны. Эти языки не асинхронны, и ленивая загрузка реализована иначе, без промисов. В JavaScript и Node.JS для ленивой загрузки связей необходимо использовать промисы. Это нестандартная техника, которая считается экспериментальной в TypeORM.