我正在使用 jooq (v3.11.9) 访问在 UTC 时间运行的 MySQL 数据库。我使用生成的实体并且正在使用 JSR-310 时间类型。我在配置中使用的选项:
<javaTimeTypes>true</javaTimeTypes>
我的理解是 MySQLdatetime
和timestamp
类型都映射到LocalDateTime
这很有意义,因为 MySQL 不会随时间存储时区信息。但是,当我在不同时区(在我的情况下为 EST)的机器上运行查询时,日期都在我的本地机器时区,即使会话时区是 UTC。
我已经确认会话时区是 UTC
dslContext.fetch("SELECT @@system_time_zone, @@global.time_zone, @@session.time_zone;")
返回
|@@system_time_zone|@@global.time_zone|@@session.time_zone|
+------------------+------------------+-------------------+
|UTC |SYSTEM |SYSTEM |
+------------------+------------------+-------------------+
时区转换示例:
dslContext.select(MY_TABLE.EPOCH_DT_TM, MY_TABLE.CREATION_TIMESTAMP).from(MY_TABLE).limit(1).fetch()
+-----------------------+-----------------------+
|epoch_dt_tm |creation_timestamp |
+-----------------------+-----------------------+
|2019-04-18T13:57:39.163|2019-09-24T16:06:47.754|
+-----------------------+-----------------------+
// CAST to STRING PROPERLY USES SESSION TIMEZONE
dslContext.select(MY_TABLE.EPOCH_DT_TM.cast(org.jooq.impl.SQLDataType.VARCHAR(100)), MY_TABLE.CREATION_TIMESTAMP.cast(org.jooq.impl.SQLDataType.VARCHAR(100))).from(MY_TABLE).limit(1).fetch()
+--------------------------+--------------------------+
|cast |cast |
+--------------------------+--------------------------+
|2019-04-18 17:57:39.163000|2019-09-24 20:06:47.754000|
+--------------------------+--------------------------+
我生成的实体中的字段:
public final TableField<MyTableRecord, LocalDateTime> EPOCH_DT_TM = createField("epoch_dt_tm", org.jooq.impl.SQLDataType.LOCALDATETIME, this, "");
public final TableField<MyTableRecord, LocalDateTime> CREATION_TIMESTAMP = createField("creation_timestamp", org.jooq.impl.SQLDataType.LOCALDATETIME.nullable(false).defaultValue(org.jooq.impl.DSL.field("CURRENT_TIMESTAMP(6)", org.jooq.impl.SQLDataType.LOCALDATETIME)), this, "");
所以我的问题是:
这是预期的行为吗?不应该用表中的原始(非时区)日期填充记录。由于某种原因,日期是否仍在后台转换为 java.sql.Timestamp?
如果这是预期的行为,是否有任何方法可以确保您在会话时区中获取日期,而不管客户端计算机上的本地时区如何?如果代码的行为取决于机器时区,则很难在本地进行测试。
预先感谢您的帮助。