TypeORM / MySQL - 拦截更新/插入查询并在“editedBy”列上自动设置应用程序用户 ID

问题描述 投票:0回答:3

我正在将 TypeORM 与 MySQL 结合使用,并通过 MySQL 触发器设置所有列和数据库表的自动审核 - 不是 TypeORM 的“记录器”功能(除非您有一些额外的信息)...

在不陷入困境的情况下,MySQL 触发器方法运行得非常好,意味着不需要应用程序端代码。

问题:我无法为MySQL查询提供登录应用程序用户的ID,而无需我们将其应用到该应用程序中创建的每个查询中。我们确实有一个中心“CRUD”类,但那是针对通用 CRUD 的,因此我们更“专业”的查询需要特殊处理 - 这是不希望的。

我们的每个表都有一个 int 字段“editedBy”,我们希望使用编辑该行的用户 ID 进行更新(通过使用我们的应用程序)。

问题: 有没有办法拦截 TypeORM 中的所有非读取查询(无论其活动记录还是查询构建器)并能够更新受影响表中的列('editedBy' int 字段)?

这将使我们的触发器解决方案完整。

附注我尝试了TypeORM的自定义日志记录功能:

... typeorm createConnection({ ....
    logger: new MyCustomLogger()
... });

class MyCustomLogger { // 'extend' has issue - works without anyway: extends Logger {

 logQuery(query, parameters, somethingelse) // WORKS
 { ... }

logQuery 确实似乎在查询(我认为)发送到 MySQL 之前触发,但我找不到如何从中提取“类似 Json”的 javascript 对象的方法,以修改每个表的“editedBy”。如果有一种方法可以找到此函数中的所有表并调整editedBy,那就太好了。很高兴尝试其他选项...这不需要更新我们包含数据库调用的许多文件。

谢谢

mysql typeorm audit-logging
3个回答
3
投票

恕我直言,使用 TypeOrm 的日志功能来修改你的查询不应该是正确的,即使它需要一点努力也是非常危险的。

如果您想管理在 TypeOrm 中完成更新插入查询的方式,最佳实践是使用自定义存储库,然后始终调用它(不要像

entityManager.getRepository(Specialist)
中那样在之后生成普通存储库,而是将您的存储库与
entityManager.getCustomRepository(SpecialistRepository)
一起使用)。

有关该主题的官方文档应该对您有很大帮助:https://github.com/typeorm/typeorm/blob/master/docs/custom-repository.md

然后在您的自定义存储库中,您可以覆盖

save
方法并添加您想要的任何内容。您的代码将是明确的,一个很好的优点是它并不适用于每个实体,因此如果您有其他不同的情况,当您想要以不同的方式保存时,您不会被卡住(您还可以添加自定义保存方法)。

如果您想通用化保存方法的处理,您可以创建一个抽象存储库来扩展 TypeOrm 存储库,然后您可以使用自定义存储库进行扩展,在其中您可以添加自定义代码,这样您就不会最终复制它在每个自定义存储库中。

SpecialistRepository<Specialist> -> CustomSaveRepository<T> -> Repository<T>

2
投票

我使用了https://github.com/skonves/express-http-context节点模块的组合将用户ID传递给TypeORM的事件订阅者功能,以更新要提交到数据库的数据:https: //github.com/typeorm/typeorm/blob/master/sample/sample5-subscribers/subscriber/EverythingSubscriber.ts


0
投票

我相信https://github.com/bemihq/typeorm库有助于自动上下文和开箱即用的数据更改跟踪。

© www.soinside.com 2019 - 2024. All rights reserved.