如何配置JOOQ保留MariaDB中Instant字段的毫秒精度?
JOOQ保留LocalDateTime/Instant的毫秒精度解决方案
问题根源在于生成的字段定义中使用了SQLDataType.LOCALDATETIME(0),其中参数0代表秒级精度,导致JOOQ自动截断了毫秒/微秒部分。以下是几种可行的解决方式:
1. 代码生成阶段全局配置精度(推荐)
在JOOQ代码生成配置中,强制指定TIMESTAMP类型的精度,生成的字段会自动带有高精度定义:
- XML配置示例:
<generator> <database> <forcedTypes> <forcedType> <name>LOCALDATETIME(6)</name> <types>TIMESTAMP</types> <!-- 匹配数据库中所有TIMESTAMP类型列 --> </forcedType> </forcedTypes> </database> </generator>
- Java代码配置示例:
new Generator() .withDatabase(new Database() .withForcedTypes(new ForcedType() .withName("LOCALDATETIME(6)") .withTypes("TIMESTAMP") ) );
配置后生成的createField代码会自动变为SQLDataType.LOCALDATETIME(6),对应数据库的TIMESTAMP(6)类型,可保留微秒精度(完全覆盖毫秒需求)。
2. 手动修改生成的字段定义(临时方案)
直接修改生成代码中的字段精度,同时更新默认值的精度定义:
public final TableField<PolicyRecord, LocalDateTime> MODIFIED_DATE = createField( DSL.name("modified_date"), SQLDataType.LOCALDATETIME(6).nullable(false).defaultValue(DSL.field(DSL.raw("current_timestamp(6)"), SQLDataType.LOCALDATETIME(6))), this, "" );
注意:此方案会在重新生成代码时被覆盖,仅适合临时测试场景。
3. 插入时显式指定精度
如果不想修改生成代码,可在插入时通过JOOQ的DSL.timestamp()方法显式传递高精度值:
// 针对Instant setField(MODIFIED_AT_FIELD_NAME, DSL.timestamp(Instant.now()), tableRecord); // 针对LocalDateTime setField(MODIFIED_AT_FIELD_NAME, DSL.timestamp(LocalDateTime.now()), tableRecord);
此方法会强制JOOQ以数据库支持的最高精度传递参数。
额外注意事项
需确保数据库表中对应的列定义为TIMESTAMP(3)(毫秒精度)或TIMESTAMP(6)(微秒精度),若数据库列本身是TIMESTAMP(0),即使JOOQ传递高精度值,数据库也会自动截断精度。
内容的提问来源于stack exchange,提问作者user3801003
相关产品推荐
相关产品推荐

