mysql 如何使用TypeORM一次更新多个表

oknwwptz  于 2022-12-10  发布在  Mysql
关注(0)|答案(1)|浏览(544)

我将TypeORM与NestJS一起使用,并希望对MySQL数据库执行以下查询:

  1. UPDATE user u, table2 t2
  2. SET u.is_active = 0, t2.is_active = 0
  3. WHERE u.id = 'id'
  4. AND t2.user_id = u.id;

关系包括:
User

  1. @OneToMany(
  2. () => Table2,
  3. (t2) => t2.user,
  4. {
  5. onDelete: 'CASCADE',
  6. eager: true
  7. }
  8. )
  9. field_table_2: Table2[]

Table2

  1. @ManyToOne(
  2. () => User,
  3. (user) => user.field_table_2
  4. )
  5. @JoinColumn({name:'user_id'})
  6. user: User

关键是:一个用户可以有多个table2,但table2中的每一行只依赖于一个用户。然后是one-to-manymany-to-one之间的关系。到目前为止一切都还好。
当我删除一个用户时,我不想将数据移到数据库中,我希望在两个表中将字段is_active设置为FALSE。
我可以使用SQL在单个查询中做到这一点,但是使用TypeORM,我只找到了使用原始SQL的解决方案:

  1. async remove(id: string) {
  2. return await this.dataSource.query(`
  3. UPDATE user u, table2 t2
  4. SET u.is_active = 0, t2.is_active = 0
  5. WHERE u.id = ?
  6. AND t2.user_id = u.id`,[id])
  7. }

但是有了ORM,我不喜欢使用原始SQL...如何使用ORM获得我想要的查询?
我知道我可以创建一个事务,首先更新一个表,然后更新另一个表,如果一切正常,则提交事务。
但是,如果我可以在一个查询中做到这一点,那么在事务中做到这一点是否有效呢?我还提到了在单个查询中的简单性。
先谢谢你。

sq1bmfud

sq1bmfud1#

TypeORM目前没有通过查询构建器或存储库方法更新单个查询中的多个表的表达方式。目前,这些操作仅限于更新单个表。
在您的例子中,如果您希望在单个查询中完成此操作,请将isActive提取到它自己的实体/表中。则用户和表2都可以与该新实体具有1-1关系。因此,您只需要更新一个表项。
否则,这可以通过两个单独的更新查询和一个事务来完成。您将如何执行更新更多地取决于选择,可以使用Repository或QueryBuilder。
managing transactions也有几个选项,其中最细粒度的是QueryRunner。
伪代码可能如下所示:

  1. queryRunner.startTransaction();
  2. try {
  3. await queryRunner
  4. .createQueryBuilder()
  5. .update(EntityA)
  6. .set({isActive: false})
  7. .execute();
  8. await queryRunner
  9. .createQueryBuilder()
  10. .update(EntityB)
  11. .set({isActive: false})
  12. .execute();
  13. await queryRunner.commitTransaction();
  14. }
  15. catch (e) {
  16. queryRunner.rollbackTransaction()
  17. }

然而,我怀疑这一切也可以使用Casade和softDelete来完成

展开查看全部

相关问题