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

Пользовательские репозитории

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

Эта страница переведена 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 используйте метод .extend класса Repository:

// 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")
}
}

Использование пользовательских репозиториев в транзакциях

Транзакции имеют собственную область выполнения: у них есть собственный query runner, entity manager и экземпляры репозиториев. Поэтому использование глобальных entity manager и репозиториев (от источника данных) не будет работать в транзакциях. Для корректного выполнения запросов в рамках транзакции необходимо использовать предоставленный entity manager и его метод getRepository. Чтобы задействовать пользовательские репозитории внутри транзакции, используйте метод withRepository предоставленного экземпляра entity manager:

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")
})