JOOQ – 相当于用于填充历史字段的hibernate拦截器?

环境:Spring应用程序,使用JOOQ 3.7,使用Postgres作为我的数据库,自动从模式生成JOOQ映射代码。

我一直在将一些代码从Hibernate移植到JOOQ。 Hibernate代码在每个上下文的基础上提取一些身份validation细节,以填充“createdBy”,“updatedBy”,日期等字段。

我目前只能通过JOOQ看到这样做的唯一方法是开发人员必须记住每次更新对象时都要编写代码来手动更新字段,我可以看到它会很乏味且容易忘记填充字段。

使用JOOQ,我是否有办法以更好的方式处理每个表上的“历史字段”而不是手工编写一堆代码?

我们目前不使用DAO,我宁愿避免编写/生成整个代码层来处理这些历史字段。

另一种选择可能是在数据库中执行此操作,如果JOOQ无法帮助解决问题,那么这可能就是我们要做的。

使用jOOQ有几种方法可以做到这一点:

1.使用RecordListenerUpdatableRecord上生成这些值

每次调用以下任何一个时都会调用RecordListener SPI:

  • TableRecord.insert()
  • UpdatableRecord.store()
  • UpdatableRecord.update()
  • UpdatableRecord.delete()
  • UpdatableRecord.refresh()

但是,在编写明确的DML语句时,不会调用此SPI。 有关更多信息,请参阅手册,此处:

2.使用VisitListener转换jOOQ生成的所有SQL语句

VisitListener SPI用于任意SQL转换操作。 您可以拦截由jOOQ生成的所有类型的SQL语句,并为它们添加其他子句,例如

 UPDATE table SET a = 1, b = 2 WHERE id = 3 

会成为

 UPDATE table SET a = 1, b = 2, updatedBy = 'me' WHERE id = 3 

本手册中记录了此SPI:

3.写入触发器

在我看来,最好的解决方案是使用触发器将这种自动生成的数据移动到数据库中。 这将允许您在迁移,手动更新或通过Java之外的其他语言(例如Perl脚本等)进行迁移时更新这些值。

4.等待jOOQ 3.10

有一个jOOQ 3.10的待处理function请求:

它将精确地实现此function,以及其他一些不错的补充,例如二维版本控制:

有趣的问题。 我想说你有两种方法。

  1. 复制Hibernate方法。 您可以将自定义操作绑定到executeEnd步骤。 这是在进入行之后发生的。 您可以访问查询对象。 基于此,您可以尝试找出如何在单独的调用中更新这两个字段(创建/修改)。 您可能希望在使用executeStart执行数据库之前扩充查询,但这将是棘手的。

  2. 设计。 如果你不想创建样板代码,那很好,但有没有理由你不能创建一些对象来处理这个前/后处理? 您可以通过一些智能代理来驱动您的查询,该代理将为您更新记录。 也许在数据库中创建一些历史表是一个好主意,它不仅要记住修改时间,还要记住已完成/更改的内容。 你不再使用hibernate了。 你不仅限于它给你的东西:)。