首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >postgres中“带时区时间戳”类型的Jooq绑定

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

Stack Overflow用户
提问于 2015-10-16 15:09:57
回答 2查看 4K关注 0票数 4

Jooq目前不支持JSR 310类型。支持要到3.8版本才会到来.

使用简单的转换器通常有效,但某些类型除外,例如postgres的TIMESTAMP WITH TIME ZONE,这需要自定义绑定。因此,我尝试编写一个,但是生成的XxxRecord类仍然使用Timestamp数据类型来处理DB中的TIMESTAMP WITH TIME ZONE字段。

要将postgres的TIMESTAMP WITH TIME ZONE 看作是 Instant**in jooq生成的类,需要在下面的代码中更改什么?**

转换器

代码语言:javascript
运行
复制
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; }
}

自定义绑定

代码语言:javascript
运行
复制
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 (提取物)

代码语言:javascript
运行
复制
<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>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-20 06:30:11

一种方法是用反斜杠转义<types>中的空格,如下所示:

代码语言:javascript
运行
复制
<types>timestamp\ with\ time\ zone</types>

您不能只在<types>中有规则的空格,因为默认情况下,org.jooq.util.AbstractDatabase将在regex中使用在注释模式下解析正则表达式来生成创建的Pattern对象忽略空格。您还可以执行类似<types>timestamp.*zone</types>的操作,或者指定您自己的。

下面是为我工作的完整的Maven jooq-codegen-maven插件标签。我还发现<binding>是不必要的。

代码语言:javascript
运行
复制
<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>
票数 6
EN

Stack Overflow用户

发布于 2019-06-20 18:39:59

在启用TIMESTAMP WITH TIME ZONE时,Jooq 3.11似乎会将javaTimeTypes转换为OffsetDateTime,而且还会抱怨customTypes被废弃,因此我无法找到其他的解决方案。

下面是我如何使用gradle jooq插件使其工作的方法:

代码语言:javascript
运行
复制
// 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。不需要外部转换器类。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33173842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档