跳转到主要内容

饥饿加载和延迟加载

饥饿加载

饥饿加载是指每次从数据库加载实体时,关联数据会自动加载。 例如:

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)

// 问题将与其关联的类别一起加载
const questions = await questionRepository.find()

饥饿加载仅在使用find*方法时生效。 如果使用QueryBuilder,则饥饿加载被禁用,必须使用leftJoinAndSelect来加载关联关系。 饥饿加载只能用于关系的一侧,不允许在关系的两侧都使用eager: true

延迟加载

延迟加载中的实体在访问时加载。 此类关系必须具有Promise作为类型 - 您将值存储在一个Promise中, 当您加载它们时,也会返回一个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。这意味着它是延迟加载的,它只能存储带有值的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])
awaitdataSource.manager.save(question)

加载延迟关系中的对象的示例:

const [question] = await dataSource.getRepository(Question).find()
const categories = await question.categories
// 现在,您可以在"categories"变量中获取所有问题的类别

注意:如果您来自其他语言(如Java、PHP等),并且习惯于在任何地方使用延迟加载,请小心。 这些语言不是异步的,因此延迟加载是通过不同的方式实现的,因此您不会在那里使用Promise。 在JavaScript和Node.js中,如果要使用延迟加载,必须使用Promise。 这是一种非标准的技术,在TypeORM中被视为实验性技术。