【发布时间】:2019-10-17 14:42:14
【问题描述】:
我正在使用带有包含 DATETIME 列的表的 SQLite 数据库。 jOOQ 默认将 DATETIME 列绑定到 java.sql.Timestamp。查询具有 DATETIME 列的表会导致每列出现 NumberFormatException(已处理)。
我正在使用 jOOQ 3.11.9。
org.jooq.impl.DefaultBinding.DefaultTimestampBinding parse 方法首次尝试将时间戳字符串值转换为数字时抛出异常。
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);
}
}
查看get0 和set0 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());
}
}
【问题讨论】: