我正在使用 MySQL 服务器,并且正在尝试使用 JOOQ API 检索时间戳。但是,我认为默认的 JOOQ 行为返回本地时区的时间,而不是 UTC(它没有使用 UNIX_TIMESTAMP()
。使用 JOOQ,我的查询看起来像
db.select(USER_TABLE.REGISTERED_ON)
.from(USER_TABLE)
.where(USER_TABLE.EMAIL.equal(email)
.fetchAny()
但是,我要执行的sql应该是这样的
SELECT UNIX_TIMESTAMP(schema.table.timestamp_col)
FROM schema.table
WHERE email="someone@domain.com"
是否可以使用 JOOQ API?如果没有,运行此查询的最佳方式是什么,因为我真的希望能够使用生成的代码(USER_TABLE、USER_TABLE.REGISTERED_ON 等)。
编辑:我现在正在执行以下操作,但它安全吗?基本上我从 JOOQ 生成的类中删除了引用。
String timestamp_field = USER_TABLE.REGISTERED_ON.toString().replace("\"", "");
Field<?> f = DSL.field("UNIX_TIMESTAMP(" + timestamp_field + ")");
Record r = db.select(f)
.from(USER_TABLE)
.where(USER_TABLE.EMAIL.equal(email))
.fetchAny();
最佳答案
有几种方法可以解决这个问题:
使用Converter
或 Binding
转换类型
你可以注册一个数据类型 Converter
或 Binding
在源代码生成器中。这样,代码生成器将生成一个 Field<YourType>
对于每个 TIMESTAMP
数据库中的字段。可能有用的类型是:
-
java.lang.Long
-
java.time.Instant
-
java.time.OffsetDateTime
(注意 jOOQ 3.7 将通过 [#4338] 支持这一点)3
使用纯 SQL
使用plain SQL每次您想使用 UNIX_TIMESTAMP()
进行显式转换时功能。您的解决方案有效:
String timestamp_field = USER_TABLE.REGISTERED_ON.toString().replace("\"", "");
Field<?> f = DSL.field("UNIX_TIMESTAMP(" + timestamp_field + ")");
但不推荐,因为:
- 你应该永远依赖任何
toString()
任何 Java 类型的实现。 - 您通常应该尽量避免使用 jOOQ 的普通 SQL API 进行字符串连接
更好的解决方案是:
DSL.field("UNIX_TIMESTAMP({0})", Long.class, USER_TABLE.REGISTERED_ON);
甚至:
public static Field<Long> unixTimestamp(Field<Timestamp> arg) {
return DSL.field("UNIX_TIMESTAMP({0})", Long.class, arg);
}
使用BIGINT
在数据库中
你当然可以使用 BIGINT
或 BIGINT UNSIGNED
在数据库中而不是 TIMESTAMP
.这样,您将始终自动拥有整数 unix 时间戳值。为了完整起见,这只是一种解决方法。
关于mysql - 使用 JOOQ 查询 Unix 时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32198344/