在jOOQ中我们如何使用Java Instant映射到Postgresql的时间戳类型?
我很惊讶地发现 jOOQ(从 3.16 开始)将时间戳绑定到 LocalDateTime
。在我看来,时间戳最自然地映射到一个Instant
,它是一个 Unix 纪元时间戳。
那么我们如何让 jOOQ 生成使用 Instant
而不是 LocalDateTime
的代码呢?我需要使用力发生器吗?
我尝试使用像这样的强制类型,但它永远不会选择我的强制类型。
.withForcedTypes(
new ForcedType()
.withUserType(Instant.class.getCanonicalName())
.withConverter(com.monsolei.data.InstantConverter.class.toString())
.withIncludeExpression("timestamp")
)
I was rather surprised to find out that jOOQ (as of 3.16) binds timestamp to LocalDateTime
. In my mind timestamp is most naturally mapped to an Instant
, it is a Unix epoch timestamp.
So how can we get jOOQ to generate code that uses Instant
instead of LocalDateTime
? Do I need to use a force generator?
I tried using forced type like this but it never picks up my forced type.
.withForcedTypes(
new ForcedType()
.withUserType(Instant.class.getCanonicalName())
.withConverter(com.monsolei.data.InstantConverter.class.toString())
.withIncludeExpression("timestamp")
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关于 PostgreSQL 时间戳数据类型
在 PostgreSQL 中(我假设您使用的是 PG),
TIMESTAMP
是TIMESTAMP Without TIME ZONE
的缩写,如下所述:https://www.postgresql.org/docs/current/datatype-datetime.html最好的 Java 类型将其映射为:
java.sql.Timestamp
(旧的 JDBC 类型,其valueOf()
和toString()
行为不支持时间区并且还可以使用您当地的时区)java.time.LocalDateTime
您也可以在 JDBC 规范,或者从存在像
java.sql.Timestamp.valueOf(LocalDateTime)
和 <代码> java.sql.Timestamp.toLocalDateTime()。事实上,您更喜欢使用
java.time.Instant
,这暗示在 PostgreSQL 中使用TIMESTAMP WITH TIME ZONE
会更好,JDBC(以及 jOOQ)将其映射到 <默认情况下为代码>OffsetDateTime。您可以在 jOOQ 中将该类型重写为INSTANT
,而无需转换器:https://www.jooq.org/doc/latest/manual/code- Generation/codegen-advanced/codegen-config-database/codegen-database-forced-types/
您还可以请参阅 PostgreSQL wiki 中的此建议:
https://wiki.postgresql.org/wiki/Don't_Do_This #Don.27t_use_timestamp_.28without_time_zone.29
您的具体配置
类型的具体尝试:
关于您映射 仅适用于名为
timestamp
的列。您可能打算将强制类型应用于键入名称?On PostgreSQL timestamp data types
In PostgreSQL (I'm assuming you're using PG),
TIMESTAMP
is short forTIMESTAMP WITHOUT TIME ZONE
as documented here: https://www.postgresql.org/docs/current/datatype-datetime.htmlThe best Java types to map that to are:
java.sql.Timestamp
(the old JDBC type, whosevalueOf()
andtoString()
behaviours do not support time zones and also work with your local time zone)java.time.LocalDateTime
You can see this also in the JDBC spec, or derive it from the fact that there are methods like
java.sql.Timestamp.valueOf(LocalDateTime)
andjava.sql.Timestamp.toLocalDateTime()
.The fact that you prefer working with
java.time.Instant
hints at it being better to useTIMESTAMP WITH TIME ZONE
in PostgreSQL, which JDBC (and thus jOOQ) maps toOffsetDateTime
by default. You can rewrite that type without a converter toINSTANT
in jOOQ:https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-forced-types/
You can also see this recommendation in the PostgreSQL wiki:
https://wiki.postgresql.org/wiki/Don't_Do_This#Don.27t_use_timestamp_.28without_time_zone.29
Your specific configuration
Regarding your specific attempts to map the type:
That only applies to column named
timestamp
. You probably meant to apply your forced type to type names?卢卡斯·埃德尔很高兴地给出了几乎完整的解决方案提示
使用文档中的转换器 - 您始终可以实现自己的数据类型绑定
我们需要定义一个 Converter
并在 codegen 中进行一些调整
人们可以使用它深思熟虑,牢记原始答案
Gladly Lukas Eder gave as an almost complete hint to a solution
using converters from docs - You can always implement your own data type binding
We need to define a Converter
And a little tweak in codegen
One can use this thoughtfully, with an original answer in mind