Работа со связями
Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →
RelationQueryBuilder — это особый тип QueryBuilder, который позволяет работать со связями.
С его помощью вы можете связывать сущности в базе данных без необходимости загружать их,
а также легко загружать связанные сущности.
Например, у нас есть сущность Post с отношением "многие-ко-многим" к Category под названием categories.
Добавим новую категорию в это отношение:
await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post)
.add(category)
Этот код эквивалентен следующему:
const postRepository = dataSource.manager.getRepository(Post)
const post = await postRepository.findOne({
where: {
id: 1,
},
relations: {
categories: true,
},
})
post.categories.push(category)
await postRepository.save(post)
Но работает эффективнее, поскольку выполняет минимальное количество операций и связывает сущности напрямую в базе,
в отличие от громоздкого вызова метода save.
Ещё одно преимущество этого подхода — отсутствие необходимости загружать все связанные сущности перед добавлением.
Например, если в одном посте содержится десять тысяч категорий, стандартное добавление новых категорий станет проблемой:
придётся загрузить пост со всеми категориями, добавить новую и сохранить. Это приведёт к высоким нагрузкам
и неприменимо в production-средах. RelationQueryBuilder решает эту проблему.
Также при связывании не обязательно использовать сами сущности — достаточно их идентификаторов. Например, добавим категорию с id = 3 к посту с id = 1:
await dataSource.createQueryBuilder().relation(Post, "categories").of(1).add(3)
Для составных первичных ключей передавайте их как карту id:
await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of({ firstPostId: 1, secondPostId: 3 })
.add({ firstCategoryId: 2, secondCategoryId: 4 })
Удаление сущностей работает аналогично добавлению:
// this code removes a category from a given post
await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post) // you can use just post id as well
.remove(category) // you can use just category id as well
Добавление и удаление работает для отношений many-to-many и one-to-many.
Для one-to-one и many-to-one используйте set:
// this code sets category of a given post
await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post) // you can use just post id as well
.set(category) // you can use just category id as well
Чтобы сбросить связь (установить null), передайте null в set:
// this code unsets category of a given post
await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post) // you can use just post id as well
.set(null)
Помимо обновления связей, конструктор реляционных запросов также позволяет загружать связанные сущности.
Например, если в сущности Post есть отношение "многие-ко-многим" categories и "многие-к-одному" user,
загрузить их можно следующим кодом:
const post = await dataSource.manager.findOneBy(Post, {
id: 1,
})
post.categories = await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post) // you can use just post id as well
.loadMany()
post.author = await dataSource
.createQueryBuilder()
.relation(Post, "user")
.of(post) // you can use just post id as well
.loadOne()