跳至主内容区

Active Record 与 Data Mapper 模式对比

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

什么是 Active Record 模式?

在 TypeORM 中,您可以同时使用 Active Record 和 Data Mapper 两种模式。

使用 Active Record 方式时,您需要在模型内部定义所有查询方法,并通过模型方法进行对象的保存、删除和加载操作。

简而言之,Active Record 模式是一种在模型内部直接访问数据库的设计方法。 您可以在维基百科上了解更多关于 Active Record 模式的信息。

示例:

import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from "typeorm"

@Entity()
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number

@Column()
firstName: string

@Column()
lastName: string

@Column()
isActive: boolean
}

所有 Active Record 实体都必须继承 BaseEntity 类,该类提供了操作实体的基础方法。 实体操作示例:

// example how to save AR entity
const user = new User()
user.firstName = "Timber"
user.lastName = "Saw"
user.isActive = true
await user.save()

// example how to remove AR entity
await user.remove()

// example how to load AR entities
const users = await User.find({ skip: 2, take: 5 })
const newUsers = await User.findBy({ isActive: true })
const timber = await User.findOneBy({ firstName: "Timber", lastName: "Saw" })

BaseEntity 已包含标准 Repository 中的大部分方法。 在多数情况下,您无需对 Active Record 实体使用 RepositoryEntityManager

假设我们需要创建按姓名查询用户的功能。 可以在 User 类中将其定义为静态方法:

import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from "typeorm"

@Entity()
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number

@Column()
firstName: string

@Column()
lastName: string

@Column()
isActive: boolean

static findByName(firstName: string, lastName: string) {
return this.createQueryBuilder("user")
.where("user.firstName = :firstName", { firstName })
.andWhere("user.lastName = :lastName", { lastName })
.getMany()
}
}

调用方式与其他方法一致:

const timber = await User.findByName("Timber", "Saw")

什么是 Data Mapper 模式?

在 TypeORM 中,您可以同时使用 Active Record 和 Data Mapper 两种模式。

使用 Data Mapper 方式时,您需要在称为"仓库"的独立类中定义所有查询方法, 并通过仓库进行对象的保存、删除和加载操作。 在 Data Mapper 中,实体仅负责定义属性及简单方法,业务逻辑非常精简。

简而言之,Data Mapper 模式是通过仓库而非模型来访问数据库的设计方法。 您可以在维基百科上了解更多关于 Data Mapper 模式的信息。

示例:

import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"

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

@Column()
firstName: string

@Column()
lastName: string

@Column()
isActive: boolean
}

实体操作示例:

const userRepository = dataSource.getRepository(User)

// example how to save DM entity
const user = new User()
user.firstName = "Timber"
user.lastName = "Saw"
user.isActive = true
await userRepository.save(user)

// example how to remove DM entity
await userRepository.remove(user)

// example how to load DM entities
const users = await userRepository.find({ skip: 2, take: 5 })
const newUsers = await userRepository.findBy({ isActive: true })
const timber = await userRepository.findOneBy({
firstName: "Timber",
lastName: "Saw",
})

如需扩展标准仓库功能,请使用自定义仓库模式

如何选择适合的模式?

选择权在您手中。 两种策略各有优劣。

在软件开发过程中,我们始终需要关注的核心问题是如何维护应用程序。 Data Mapper 模式通过提升代码可维护性,在大型应用中效果显著; 而 Active Record 模式则通过保持简洁性,在小型应用中表现更优。