如何使用 TypeORM 中的 QueryBuilder 更新具有关系的实体
How to update an entity with relations using QueryBuilder in TypeORM
我有UserEntity
和AddressEntity
,它们的关系是OneToOne
,也就是说一个用户可能只有一个地址。 UserEntity
有字段 firstName
、secondName
、address
。 AddressEntity
有字段 country
和 city
.
如果我想更新 UserEntity
而不对其关系进行更新,我会这样做:
await entityManager.getRepository(UserEntity)
.createQueryBuilder('users')
.update(UserEntity)
.set(updateUserObject)
.where('users.id = :userId', { userId })
.execute();
其中 updateUserObject
由请求正文构成。也就是说,如果我需要更新 firstName
,对象将如下所示:{ firstName: 'Joe' }
。现在不清楚的是如果我有以下 updateUserObject
:
如何使用该构建器
{
firstName: "Bob",
address: {
"city": "Ottawa"
}
}
官方文档没有解决这种情况。
您可以使用 preload and save 方法实现此目的。
更新您的 UserEntity
类似于以下内容:
@Entity('user')
export class UserEntity {
...
@OneToOne(
() => AddressEntity,
{
// Make sure that when you delete or update a user, it will affect the
// corresponding `AddressEntity`
cascade: true,
// Make sure when you use `preload`, `AddressEntity` of the user will also
// return (This means whenever you use any kind of `find` operations on
// `UserEntity`, it would load this entity as well)
eager: true
}
)
@JoinColumn()
address: AddressEntity;
}
现在使用 entityManager
,您可以使用以下方式更新您想要的所有字段:
const partialUserEntity = {
id: userId,
firstName: "Bob",
address: {
"city": "Ottawa"
}
};
const userRepository = await entityManager.getRepository(UserEntity);
// Here we load the current user entity value from the database and replace
// all the related values from `partialUserEntity`
const updatedUserEntity = userRepository.preload(partialUserEntity);
// Here we update (create if not exists) `updatedUserEntity` to the database
await userRepository.save(updatedUserEntity);
但是,您需要确保您的 UserEntity
始终关联一个 AddressEntity
。否则,在执行 save
方法之前,您必须像下面那样为 AddressEntity
生成一个 id
。
/*
* If `updatedUserEntity.address.id` is `undefined`
*/
// `generateIDForAddress` is a function which would return an `id`
const generatedIDForAddress = generateIDForAddress();
const partialUserEntity = {
id: userId,
firstName: "Bob",
address: {
"id": generatedIDForAddress,
"city": "Ottawa"
}
};
请注意,在后台,typeorm 将 运行 UPDATE
语句分别用于 UserEntity
和 AddressEntity
。这只是对多个join语句(执行preload
方法时)和update语句(执行save
方法时)的封装,开发者可以很容易的实现这个场景。
希望对您有所帮助。干杯!
我有UserEntity
和AddressEntity
,它们的关系是OneToOne
,也就是说一个用户可能只有一个地址。 UserEntity
有字段 firstName
、secondName
、address
。 AddressEntity
有字段 country
和 city
.
如果我想更新 UserEntity
而不对其关系进行更新,我会这样做:
await entityManager.getRepository(UserEntity)
.createQueryBuilder('users')
.update(UserEntity)
.set(updateUserObject)
.where('users.id = :userId', { userId })
.execute();
其中 updateUserObject
由请求正文构成。也就是说,如果我需要更新 firstName
,对象将如下所示:{ firstName: 'Joe' }
。现在不清楚的是如果我有以下 updateUserObject
:
{
firstName: "Bob",
address: {
"city": "Ottawa"
}
}
官方文档没有解决这种情况。
您可以使用 preload and save 方法实现此目的。
更新您的 UserEntity
类似于以下内容:
@Entity('user')
export class UserEntity {
...
@OneToOne(
() => AddressEntity,
{
// Make sure that when you delete or update a user, it will affect the
// corresponding `AddressEntity`
cascade: true,
// Make sure when you use `preload`, `AddressEntity` of the user will also
// return (This means whenever you use any kind of `find` operations on
// `UserEntity`, it would load this entity as well)
eager: true
}
)
@JoinColumn()
address: AddressEntity;
}
现在使用 entityManager
,您可以使用以下方式更新您想要的所有字段:
const partialUserEntity = {
id: userId,
firstName: "Bob",
address: {
"city": "Ottawa"
}
};
const userRepository = await entityManager.getRepository(UserEntity);
// Here we load the current user entity value from the database and replace
// all the related values from `partialUserEntity`
const updatedUserEntity = userRepository.preload(partialUserEntity);
// Here we update (create if not exists) `updatedUserEntity` to the database
await userRepository.save(updatedUserEntity);
但是,您需要确保您的 UserEntity
始终关联一个 AddressEntity
。否则,在执行 save
方法之前,您必须像下面那样为 AddressEntity
生成一个 id
。
/*
* If `updatedUserEntity.address.id` is `undefined`
*/
// `generateIDForAddress` is a function which would return an `id`
const generatedIDForAddress = generateIDForAddress();
const partialUserEntity = {
id: userId,
firstName: "Bob",
address: {
"id": generatedIDForAddress,
"city": "Ottawa"
}
};
请注意,在后台,typeorm 将 运行 UPDATE
语句分别用于 UserEntity
和 AddressEntity
。这只是对多个join语句(执行preload
方法时)和update语句(执行save
方法时)的封装,开发者可以很容易的实现这个场景。
希望对您有所帮助。干杯!