JOOQ - 相当于用于填充历史字段的休眠拦截器?
JOOQ - equivalent of hibernate interceptor for populating history fields?
环境:
Spring 应用程序,使用 JOOQ 3.7,从模式自动生成 JOOQ 映射代码,使用 Postgres 作为我的数据库。
我一直在将一些代码从 Hibernate 移植到 JOOQ。
Hibernate 代码提取一些隐藏在每个上下文基础上的身份验证详细信息,以填充 "createdBy"、"updatedBy"、日期等字段
目前我能看到用 JOOQ 做到这一点的唯一方法是开发人员每次更新对象时都必须记住编写代码来手动更新字段,我知道这会很乏味并且很容易忘记填充字段。
使用 JOOQ,有什么方法可以比手动编写一堆代码更好地处理每个 table 上的 "history fields"?
我们目前不使用 DAO,我宁愿避免 writing/generating 整个代码层来处理这些历史字段。
另一种选择可能是在数据库中执行此操作,如果 JOOQ 无法帮助解决问题,那很可能就是我们要做的。
有趣的问题。我会说你在这里有两种方法。
复制Hibernate方法。您可以将自定义操作绑定到 executeEnd step. This is happening just after entering row. You can access query 对象。基于此,您可以尝试弄清楚如何在单独的调用中更新这两个字段 (created/modified)。在使用 executeStart 执行到数据库之前,您可能还想增加查询,但这会很棘手。
设计。如果您不想创建样板代码,那很好,但是有什么原因导致您无法创建某个对象来为您处理此 pre/post 处理?您可以通过一些将为您更新记录的智能代理来驱动您的查询。也许在数据库中创建一些历史记录 table 是个好主意,这样不仅可以记住修改时间,还可以记住已经发生的内容 done/changed。你不再使用休眠了。你不局限于它给你的东西:).
有几种方法可以用 jOOQ 做到这一点:
1。使用 RecordListener
在 UpdatableRecord
上生成这些值
每次您调用以下任何一项时都会调用 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.17
从 jOOQ 3.17 开始,可以使用审计列和其他类型的客户端计算列:
它将精确地实现此功能,以及一些其他不错的添加,例如二维版本控制,这可能会在未来的版本中可用:
- #4704 SQL:2011 时间有效性
环境: Spring 应用程序,使用 JOOQ 3.7,从模式自动生成 JOOQ 映射代码,使用 Postgres 作为我的数据库。
我一直在将一些代码从 Hibernate 移植到 JOOQ。 Hibernate 代码提取一些隐藏在每个上下文基础上的身份验证详细信息,以填充 "createdBy"、"updatedBy"、日期等字段
目前我能看到用 JOOQ 做到这一点的唯一方法是开发人员每次更新对象时都必须记住编写代码来手动更新字段,我知道这会很乏味并且很容易忘记填充字段。
使用 JOOQ,有什么方法可以比手动编写一堆代码更好地处理每个 table 上的 "history fields"?
我们目前不使用 DAO,我宁愿避免 writing/generating 整个代码层来处理这些历史字段。
另一种选择可能是在数据库中执行此操作,如果 JOOQ 无法帮助解决问题,那很可能就是我们要做的。
有趣的问题。我会说你在这里有两种方法。
复制Hibernate方法。您可以将自定义操作绑定到 executeEnd step. This is happening just after entering row. You can access query 对象。基于此,您可以尝试弄清楚如何在单独的调用中更新这两个字段 (created/modified)。在使用 executeStart 执行到数据库之前,您可能还想增加查询,但这会很棘手。
设计。如果您不想创建样板代码,那很好,但是有什么原因导致您无法创建某个对象来为您处理此 pre/post 处理?您可以通过一些将为您更新记录的智能代理来驱动您的查询。也许在数据库中创建一些历史记录 table 是个好主意,这样不仅可以记住修改时间,还可以记住已经发生的内容 done/changed。你不再使用休眠了。你不局限于它给你的东西:).
有几种方法可以用 jOOQ 做到这一点:
1。使用 RecordListener
在 UpdatableRecord
上生成这些值
每次您调用以下任何一项时都会调用 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.17
从 jOOQ 3.17 开始,可以使用审计列和其他类型的客户端计算列:
它将精确地实现此功能,以及一些其他不错的添加,例如二维版本控制,这可能会在未来的版本中可用:
- #4704 SQL:2011 时间有效性