TypeORM / MySQL - 拦截 Update/Insert 在 'editedBy' 列上自动查询和设置应用程序用户 ID

TypeORM / MySQL - Intercept Update/Insert Queries and set app user ID automatically on 'editedBy' column

我将 TypeORM 与 MySQL 一起使用,并通过 MySQL 触发器设置对所有列和数据库 table 的自动审计 - 而不是 TypeORM 的 "Logger" 功能(除非你有一些额外的信息)...

没有陷入困境,MySQL 触发器方法非常有效,这意味着不需要应用程序端代码。

问题:我无法以不需要我们将其应用到在此创建的每个查询中的方式向 MySQL 查询提供已登录应用程序用户的 ID应用程序。我们确实有一个中央 "CRUD" class,但那是针对通用 CRUD 的,因此我们的更多 "specialist" 查询将需要特殊处理 - 不需要。

我们的每个 table 都有一个 int 字段 "editedBy",我们想在其中更新编辑该行的用户 ID(通过使用我们的应用程序)。

问题:有没有办法拦截 TypeORM 中的所有非读取查询(不管它是活动记录还是查询构建器)并能够更新受影响的列tables('editedBy' 整数字段)?

这样我们的触发器解决方案就完成了。

P.S。我尝试了 TypeORM 的自定义日志功能:

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

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

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

logQuery 确实在查询(我认为)发送到 MySQL 之前触发,但我找不到如何从中提取 "Json-like" javascript 对象的方法, 修改每个 table 的 "editedBy"。如果有办法找到这个函数内的所有 table 并调整 editedBy 就好了。很高兴尝试其他选项...不需要更新我们拥有的许多包含数据库调用的文件。

谢谢

恕我直言,使用 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>

我使用了https://github.com/skonves/express-http-context node module to pass user ID to TypeORM's Event Subscribers feature to make the update to data about to be submitted to DB: https://github.com/typeorm/typeorm/blob/master/sample/sample5-subscribers/subscriber/EverythingSubscriber.ts

的组合