跳至主内容区

自定义存储库

非官方测试版翻译

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

你可以创建自定义存储库来封装数据库操作方法。 例如,假设我们需要一个 findByName(firstName: string, lastName: string) 方法, 用于根据名字和姓氏搜索用户。 最佳实践是将此方法放在 Repository 中, 这样就能通过 userRepository.findByName(...) 调用。 通过自定义存储库即可实现此功能。

创建自定义存储库有以下几种方式:

如何创建自定义存储库?

通常做法是将存储库实例赋值给全局导出变量, 并在整个应用中引用该变量,例如:

// user.repository.ts
export const UserRepository = dataSource.getRepository(User)

// user.controller.ts
export class UserController {
users() {
return UserRepository.find()
}
}

要扩展 UserRepository 的功能,可使用 Repository 类的 .extend 方法:

// user.repository.ts
export const UserRepository = dataSource.getRepository(User).extend({
findByName(firstName: string, lastName: string) {
return this.createQueryBuilder("user")
.where("user.firstName = :firstName", { firstName })
.andWhere("user.lastName = :lastName", { lastName })
.getMany()
},
})

// user.controller.ts
export class UserController {
users() {
return UserRepository.findByName("Timber", "Saw")
}
}

在事务中使用自定义存储库

事务具有独立的执行作用域:包含专属的查询运行器、实体管理器及存储库实例。 因此全局(数据源的)实体管理器和存储库在事务中无效。 要在事务作用域内正确执行查询,必须使用事务提供的实体管理器 及其 getRepository 方法。若要在事务中使用自定义存储库, 需调用该实体管理器实例的 withRepository 方法:

await connection.transaction(async (manager) => {
// in transactions you MUST use manager instance provided by a transaction,
// you cannot use global entity managers or repositories,
// because this manager is exclusive and transactional

const userRepository = manager.withRepository(UserRepository)
await userRepository.createAndSave("Timber", "Saw")
const timber = await userRepository.findByName("Timber", "Saw")
})