在SQLite中使用DATETIME列时如何避免NumberFormatException?

时间:2019-06-01 03:46:38

标签: java sqlite jooq

我正在使用带有包含DATETIME列的表的SQLite数据库。 jOOQ默认将DATETIME列绑定到java.sql.Timestamp。用DATETIME列查询表会为每列导致NumberFormatException(已处理)。

我正在使用jOOQ 3.11.9。

org.jooq.impl.DefaultBinding.DefaultTimestampBinding解析方法在首次尝试将时间戳记字符串值转换为数字时引发了异常。

private static final long parse(Class < ? extends java.util.Date > type, String date) throws SQLException {

    // Try reading a plain number first
    try {
        return Long.valueOf(date);
    }

    // If that fails, try reading a formatted date
    catch (NumberFormatException e) {

        // [#7325] In SQLite dates could be stored in both ISO standard formats:
        //         With T (default standard), or without T (optional standard, JDBC standard)
        date = StringUtils.replace(date, "T", " ");

        if (type == Timestamp.class)
            return Timestamp.valueOf(date).getTime();

        // Dates may come with " 00:00:00". This is safely trimming time information
        else if (type == Date.class)
            return Date.valueOf(date.split(" ")[0]).getTime();

        else if (type == Time.class)
            return Time.valueOf(date).getTime();

        throw new SQLException("Could not parse date " + date, e);
    }
}

查看get0set0 DefaultTimestampBinding方法,始终将时间戳记设置为字符串。为什么没有将SQLite的时间戳作为时间戳传递给JDBC语句/结果的原因?有什么方法可以覆盖此行为或避免异常?

Override
final void set0(BindingSetStatementContext < U > ctx, Timestamp value) throws SQLException {
    if (ctx.family() == SQLITE)
        ctx.statement().setString(ctx.index(), value.toString());
    else
        ctx.statement().setTimestamp(ctx.index(), value);
}

@Override
final Timestamp get0(BindingGetResultSetContext < U > ctx) throws SQLException {

    // SQLite's type affinity needs special care...
    if (ctx.family() == SQLDialect.SQLITE) {
        String timestamp = ctx.resultSet().getString(ctx.index());
        return timestamp == null ? null : new Timestamp(parse(Timestamp.class, timestamp));
    } else {
        return ctx.resultSet().getTimestamp(ctx.index());
    }
}

1 个答案:

答案 0 :(得分:1)

虽然您可以在代码生成器中注册自定义绑定,但是请注意,此问题将在即将发布的jOOQ 3.12版本以及下一个3.11服务版本中得到解决。有关详细信息,请参见https://github.com/jOOQ/jOOQ/issues/8736