简体   繁体   English

postgres中的“带时区的时间戳”的Jooq绑定

[英]Jooq binding for “timestamp with time zone” type in postgres

Jooq currently does not support JSR 310 types and support will not come until v3.8 . Jooq目前不支持JSR 310类型直到v3.8才会支持

Using simple converters generally works, except for certain types, such as postgres' TIMESTAMP WITH TIME ZONE , which requires a custom binding. 使用简单的转换器通常可以工作,除了某些类型,例如postgres'TIMESTAMP TIMESTAMP WITH TIME ZONE ,它需要自定义绑定。 So I have tried to write one but the generated XxxRecord classes still use a Timestamp data type for the TIMESTAMP WITH TIME ZONE fields in my DB. 所以我尝试编写一个,但生成的XxxRecord类仍然在我的数据库中TIMESTAMP WITH TIME ZONE字段的Timestamp数据类型。

What do I need to change in my code below to see postgres' TIMESTAMP WITH TIME ZONE as an Instant in jooq's generated classes? 在下面的代码中我需要更改什么才能在jooq生成的类中看到postgres'TIMESTAMP TIMESTAMP WITH TIME ZONE作为Instant

Converter 变流器

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; }
}

Custom binding 自定义绑定

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 (extracts) 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>

One way would be to escape the spaces in <types> with backslashes, as follows: 一种方法是使用反斜杠转义<types>的空格,如下所示:

<types>timestamp\ with\ time\ zone</types>

You can't just have regular spaces in <types> because by default, org.jooq.util.AbstractDatabase will parse regular expressions in COMMENTS mode which makes the created Pattern object ignore whitespace in your regex. 您不能只在<types>有常规空格,因为默认情况下, org.jooq.util.AbstractDatabase在COMMENTS模式下解析正则表达式,这会使创建的Pattern对象忽略正则表达式中的空格 You could also do something like <types>timestamp.*zone</types> , or specify your own <regexFlags> . 您还可以执行类似<types>timestamp.*zone</types> ,或指定您自己的<regexFlags>

The following is the full Maven jooq-codegen-maven plugin tag that works for me. 以下是适用于我的完整Maven jooq-codegen-maven插件标记。 I also found the <binding> to be unnecessary. 我还发现<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 seems to turn a TIMESTAMP WITH TIME ZONE into an OffsetDateTime when javaTimeTypes is enabled, and it also complains about customTypes being deprecated, so I wasn't able to get the other answers to work for me. Jooq 3.11似乎把一个TIMESTAMP WITH TIME ZONEOffsetDateTimejavaTimeTypes被启用,也抱怨customTypes被弃用,所以我没能得到其他的答案为我工作。

Here's how I was able to get this to work, using the gradle jooq plugin: 以下是我使用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'
    }
}

It should be pretty easy to turn this into XML for Maven or manual invocation of the code generator, as the gradle plugin's parameters exactly match the structure of the XML. 将它转换为Maven的XML或手动调用代码生成器应该非常容易,因为gradle插件的参数与XML的结构完全匹配。 Note that Groovy syntax requires the doubling of the backslashes in the types pattern, so that would need to be adjusted if converting to XML. 请注意,Groovy语法要求在types模式中加倍反斜杠,因此如果转换为XML则需要进行调整。

This uses an inline converter to turn the OffsetDateTime that Jooq currently uses into an Instant . 这使用内联转换器将Jooq当前使用的OffsetDateTime转换为Instant No external converter class is necessary. 无需外部转换器类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 jOOQ:使用TIME ZONE解析Oracle TIMESTAMP时出错 - jOOQ: Error parsing Oracle TIMESTAMP WITH TIME ZONE 当我在 Jooq 中插入日期时,出现此错误:column creation_date is of type timestamp with time zone but expression is of type character varying - When I insert a date in Jooq, I get this error: column creation_date is of type timestamp with time zone but expression is of type character varying 如何使用 JOOQ 将 TIMESTAMP WITH TIME ZONE 插入 HSQLDB - How to insert TIMESTAMP WITH TIME ZONE into HSQLDB using JOOQ 使用 postgres 和 jooq 按时间分组 - Group by time with postgres and jooq Postgres 中没有 TIME ZONE DEFAULT CURRENT_TIMESTAMP 字段的 JPA 模型类? - JPA Model Class for field TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP in Postgres? 带时间戳的时间戳(6)与时间戳 - TIMESTAMP (6) WITH TIME ZONE to Time stamp 毫秒未从 java new Date() function 正确转换为带有时区的 postgres 时间戳 - Milliseconds are not converted properly from java new Date() function to the postgres Timestamp with time Zone PostgreSQL 参数错误(timestamp with time zone, timestamp without time zone) - PostgreSQL Parameter error (timestamp with time zone, timestamp without time zone) JavaLite,通过时区获取TIMESTAMP(6) - JavaLite, get TIMESTAMP(6) WITH TIME ZONE 错误:列“DOJ”的类型是没有时区的时间戳,但表达式的类型是字符变化 - ERROR: column "DOJ" is of type timestamp without time zone but expression is of type character varying
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM