自定义仓库
您可以创建一个自定义仓库,其中应包含与数据库交互的方法。
例如,假设我们想要有一个名为 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) => {
// 在事务中,您必须使用事务提供的管理器实例,
// 不能使用全局实体管理器或仓库,
// 因为这个管理器是独占的且具有事务性
const userRepository = manager.withRepository(UserRepository)
await userRepository.createAndSave("Timber", "Saw")
const timber = await userRepository.findByName("Timber", "Saw")
})