【问题标题】:Saving fractional seconds to TIME datatype in DB using JOOQ使用 JOOQ 将小数秒保存到数据库中的 TIME 数据类型
【发布时间】:2019-11-08 03:30:04
【问题描述】:

我需要将来自外部 API 的数据存储到 MariaDB。其中一个字段以 java.time.LocalTime 的形式出现,并使用 TIME 类型存储。它可以包含几分之一秒。我正在使用 JOOQ 进行 SQL 构建/执行。

DB 字段是使用TIME(6) 创建的,并且数据在此处正确列为“hh:mm:ss.ssssss”。然而,每当我从我的应用程序中保存数据时,小数部分就会被清零。例如:12:34:56.123456 -> 12:34:56.000000

我意识到这是由于 JOOQ 在内部使用了java.sql.Time,并且由于它扩展了java.util.Date,因此丢失了部分精度。我正在尝试找到解决此问题的方法,以便我仍然可以存储时间的到来。

我尝试过的:

  1. 使用自定义org.jooq.Converterjava.sql.Timejava.time.LocalTime 之间转换,但与默认org.jooq.impl.TimeToLocalTimeConverter 不同,它保留时间对象的毫秒部分。这允许我以毫秒精度(逗号后 3 位)保存和检索值。

  2. 从 Internet 上的一些资源看来,应该可以将 LocalTimeLocalDateTime 直接与较新的 JDBC 驱动程序一起使用。为了尝试,我尝试使用从java.time.LocalTime 转换为java.time.LocalTimeorg.jooq.Converter,基本上只是让对象通过。我希望 JOOQ 然后只使用这个转换器并将LocalTime 直接传递给数据库,但不幸的是它不能像这样工作。默认实现仍会处理该值,并且会丢失数据的小数部分。

  3. 为了超越 JOOQ 的默认功能,我尝试创建一个自定义的 org.jooq.Binding,它将直接使用传入的对象。但是,当我尝试这样做时,使用JOOQ custom binding example 作为基础,我无法实现必要的方法。例如,示例有:

    public void get(BindingGetStatementContext<JsonElement> ctx) throws SQLException {
        ctx.convert(converter()).value(ctx.statement().getString(ctx.index()));
    }

...我需要做类似的事情:

    public void get(BindingGetStatementContext<LocalTime> ctx) throws SQLException {
        ctx.convert(converter()).value(ctx.statement().getLocalTime(ctx.index()));
    }

但是java.sql.CallableStatement没有这样的方法。我是否误解了什么应该是可能的?

我知道JOOQ which will support for fractional seconds in the future 中有一个未解决的问题,但这似乎还有很长的路要走,我正在寻找一个现在可以工作的解决方案。

【问题讨论】:

  • JDBC 没有为java.time 类型定义显式setter 或getter,而是通过getObject/setObject 定义访问。您需要使用getObject(ctx.index(), LocalTime.class)(假设您的数据库驱动程序兼容 JDBC 4.2)。

标签: java jdbc time mariadb jooq


【解决方案1】:

您无法使用Converter 解决此问题,因为 jOOQ 将在内部继续使用 JDBC 类型 java.sql.Time 在幕后。您需要实现自己的Binding。如果您的 JDBC 驱动程序支持 JSR 310 类型,您遇到问题的方法必须如下所示:

public void get(BindingGetStatementContext<LocalTime> ctx) throws SQLException {
    ctx.value(ctx.statement().getObject(ctx.index(), LocalTime.class));
}

注意,在这种情况下,您不应使用 Converter,因为您已经确保从 JDBC 正确获取了 Binding&lt;T, U&gt;&lt;U&gt; 类型(其中 T = java.sql.TimeU = java.time.LocalTime) .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 2020-02-12
    相关资源
    最近更新 更多