"timestamp with time zone" postgres 中的 Jooq 绑定
Jooq binding for "timestamp with time zone" type in postgres
and support will not come until v3.8.
使用简单的转换器通常可以工作,但某些类型除外,例如 postgres 的 TIMESTAMP WITH TIME ZONE
,它需要自定义绑定。所以我试着写一个,但生成的 XxxRecord
类 仍然使用 Timestamp
数据类型作为我数据库中的 TIMESTAMP WITH TIME ZONE
字段。
我需要在下面的代码中更改什么才能将 postgres 的 TIMESTAMP WITH TIME ZONE
视为 jooq 生成的 类 中的 Instant
?
转换器
public class TimestampConverter implements Converter<Timestamp, Instant> {
@Override public Instant from(Timestamp ts) {
return ts == null ? null : ts.toInstant();
}
@Override public Timestamp to(Instant instant) {
return instant == null ? null : Timestamp.from(instant);
}
@Override public Class<Timestamp> fromType() { return Timestamp.class; }
@Override public Class<Instant> toType() { return Instant.class; }
}
自定义绑定
public class TimestampBinding implements Binding<Timestamp, Instant> {
private static final Converter<Timestamp, Instant> converter = new TimestampConverter();
private final DefaultBinding<Timestamp, Instant> delegate =
new DefaultBinding<> (converter());
@Override public Converter<Timestamp, Instant> converter() { return converter; }
@Override public void sql(BindingSQLContext<Instant> ctx) throws SQLException {
delegate.sql(ctx);
}
//etc. same for all other overriden methods.
}
pom.xml(摘录)
<customType>
<name>java.time.Instant</name>
<type>java.time.Instant</type>
<binding>xxx.TimestampBinding</binding>
</customType>
...
<forcedType>
<name>java.time.Instant</name>
<types>timestamp with time zone</types>
</forcedType>
一种方法是用反斜杠转义 <types>
中的空格,如下所示:
<types>timestamp\ with\ time\ zone</types>
您不能只在 <types>
中使用常规空格,因为默认情况下,org.jooq.util.AbstractDatabase
将 parse regular expressions in COMMENTS mode which makes the created Pattern
object ignore whitespace in your regex. You could also do something like <types>timestamp.*zone</types>
, or specify your own <regexFlags>
.
以下是适用于我的完整 Maven jooq-codegen-maven
插件标签。我还发现 <binding>
是不必要的。
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>3.7.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<jdbc>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql:postgres</url>
<user>postgres</user>
<password>mypass</password>
</jdbc>
<generator>
<database>
<customTypes>
<customType>
<name>Instant</name>
<type>java.time.Instant</type>
<converter>xxx.TimestampConverter</converter>
</customType>
</customTypes>
<forcedTypes>
<forcedType>
<name>Instant</name>
<types>timestamp\ with\ time\ zone</types>
</forcedType>
</forcedTypes>
<name>org.jooq.util.postgres.PostgresDatabase</name>
<includes>author</includes>
<excludes/>
<inputSchema>public</inputSchema>
</database>
<target>
<packageName>xxx.table</packageName>
<directory>target/generated-sources/jooq</directory>
</target>
</generator>
</configuration>
</plugin>
Jooq 3.11 似乎在启用 javaTimeTypes
时将 TIMESTAMP WITH TIME ZONE
变成了 OffsetDateTime
,并且它还抱怨 customTypes
被弃用,所以我不是能够得到对我有用的其他答案。
以下是我如何使用 gradle jooq 插件让它工作:
// inside the jooq...generator.database of build.gradle:
forcedTypes {
forcedType {
userType = 'java.time.Instant'
converter = '''
org.jooq.Converter.ofNullable(
java.time.OffsetDateTime.class,
java.time.Instant.class,
o -> o.toInstant(),
i -> i.atOffset(java.time.ZoneOffset.UTC))
'''
types = 'timestamp\ with\ time\ zone'
}
}
对于 Maven 或手动调用代码生成器,将其转换为 XML 应该很容易,因为 gradle 插件的参数与 XML 的结构完全匹配。请注意 Groovy 语法要求 types
模式中的反斜杠加倍,因此如果转换为 XML.
则需要进行调整
这使用内联转换器将 Jooq 当前使用的 OffsetDateTime
转换为 Instant
。无需外部转换器 class。
使用简单的转换器通常可以工作,但某些类型除外,例如 postgres 的 TIMESTAMP WITH TIME ZONE
,它需要自定义绑定。所以我试着写一个,但生成的 XxxRecord
类 仍然使用 Timestamp
数据类型作为我数据库中的 TIMESTAMP WITH TIME ZONE
字段。
我需要在下面的代码中更改什么才能将 postgres 的 TIMESTAMP WITH TIME ZONE
视为 jooq 生成的 类 中的 Instant
?
转换器
public class TimestampConverter implements Converter<Timestamp, Instant> {
@Override public Instant from(Timestamp ts) {
return ts == null ? null : ts.toInstant();
}
@Override public Timestamp to(Instant instant) {
return instant == null ? null : Timestamp.from(instant);
}
@Override public Class<Timestamp> fromType() { return Timestamp.class; }
@Override public Class<Instant> toType() { return Instant.class; }
}
自定义绑定
public class TimestampBinding implements Binding<Timestamp, Instant> {
private static final Converter<Timestamp, Instant> converter = new TimestampConverter();
private final DefaultBinding<Timestamp, Instant> delegate =
new DefaultBinding<> (converter());
@Override public Converter<Timestamp, Instant> converter() { return converter; }
@Override public void sql(BindingSQLContext<Instant> ctx) throws SQLException {
delegate.sql(ctx);
}
//etc. same for all other overriden methods.
}
pom.xml(摘录)
<customType>
<name>java.time.Instant</name>
<type>java.time.Instant</type>
<binding>xxx.TimestampBinding</binding>
</customType>
...
<forcedType>
<name>java.time.Instant</name>
<types>timestamp with time zone</types>
</forcedType>
一种方法是用反斜杠转义 <types>
中的空格,如下所示:
<types>timestamp\ with\ time\ zone</types>
您不能只在 <types>
中使用常规空格,因为默认情况下,org.jooq.util.AbstractDatabase
将 parse regular expressions in COMMENTS mode which makes the created Pattern
object ignore whitespace in your regex. You could also do something like <types>timestamp.*zone</types>
, or specify your own <regexFlags>
.
以下是适用于我的完整 Maven jooq-codegen-maven
插件标签。我还发现 <binding>
是不必要的。
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>3.7.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<jdbc>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql:postgres</url>
<user>postgres</user>
<password>mypass</password>
</jdbc>
<generator>
<database>
<customTypes>
<customType>
<name>Instant</name>
<type>java.time.Instant</type>
<converter>xxx.TimestampConverter</converter>
</customType>
</customTypes>
<forcedTypes>
<forcedType>
<name>Instant</name>
<types>timestamp\ with\ time\ zone</types>
</forcedType>
</forcedTypes>
<name>org.jooq.util.postgres.PostgresDatabase</name>
<includes>author</includes>
<excludes/>
<inputSchema>public</inputSchema>
</database>
<target>
<packageName>xxx.table</packageName>
<directory>target/generated-sources/jooq</directory>
</target>
</generator>
</configuration>
</plugin>
Jooq 3.11 似乎在启用 javaTimeTypes
时将 TIMESTAMP WITH TIME ZONE
变成了 OffsetDateTime
,并且它还抱怨 customTypes
被弃用,所以我不是能够得到对我有用的其他答案。
以下是我如何使用 gradle jooq 插件让它工作:
// inside the jooq...generator.database of build.gradle:
forcedTypes {
forcedType {
userType = 'java.time.Instant'
converter = '''
org.jooq.Converter.ofNullable(
java.time.OffsetDateTime.class,
java.time.Instant.class,
o -> o.toInstant(),
i -> i.atOffset(java.time.ZoneOffset.UTC))
'''
types = 'timestamp\ with\ time\ zone'
}
}
对于 Maven 或手动调用代码生成器,将其转换为 XML 应该很容易,因为 gradle 插件的参数与 XML 的结构完全匹配。请注意 Groovy 语法要求 types
模式中的反斜杠加倍,因此如果转换为 XML.
这使用内联转换器将 Jooq 当前使用的 OffsetDateTime
转换为 Instant
。无需外部转换器 class。