在MySQL数据库中,我有一个数据类型为DATETIME
的列。使用JDBC,可以将这些值设置为timestamps in a certain timezone。这可以用jOOQ来完成吗?
我有一个包含此架构的示例表:
CREATE SCHEMA IF NOT EXISTS `my_test_db` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin ;
CREATE TABLE IF NOT EXISTS `my_test_db`.`my_table` (
`id` INT NOT NULL AUTO_INCREMENT ,
`my_time` DATETIME NOT NULL ,
PRIMARY KEY (`id`) )
我对DATETIME
列中的TIMESTAMP
列,不特别感兴趣。我只想使用UTC时间戳 - 无论我在哪里查询数据,从哪里得到时间戳都要插入数据库。
使用JDBC,我可以像在此示例应用程序中一样解决问题:
import java.sql.*;
import java.util.Calendar;
import java.util.TimeZone;
public class MyTest {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/my_test_db?"
+ "useTimezone=true&useLegacyDatetimeCode=false&serverTimezone=UTC");
PreparedStatement prepStmt = conn.prepareStatement(
"INSERT INTO `my_test_db`.`my_table` (`my_time`) VALUES (?)");
// NB: this particular timestamp is just an example; I actually get
// timestamps from elsewhere but I can be certain that they’re in UTC.
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
// This is the interesting line which I’d like to port to jOOQ; I can pass
// in an additional “Calendar” object from which time zone information is
// taken into account for the new “DATETIME” value:
prepStmt.setTimestamp(1, new Timestamp(cal.getTimeInMillis()), cal);
prepStmt.executeUpdate();
} finally {
if (conn != null) {
conn.close();
}
}
}
}
在jOOQ中,我似乎无法指定时区信息:
// …
DSLContext dslContext = DSL.using(conn);
dslContext.insertInto(MY_TABLE)
.set(MY_TABLE.MY_TIME, new Timestamp(cal.getTimeInMillis()))
.execute();
因此,使用上述jOOQ代码创建的任何时间戳都在系统默认时区。我可以改变吗?
答案 0 :(得分:0)
我使用一个新类来解决它,返回一个实现utc_timestamp()函数的jOOQ字段。
package org.jooq.impl;
import ...
public class Custom_MySQL_UTCTimestamp extends AbstractFunction<Timestamp> {
public Custom_MySQL_UTCTimestamp() {
super("utc_timestamp", SQLDataType.TIMESTAMP);
}
@Override
final Field<Timestamp> getFunction0(Configuration configuration) {
if(configuration.family() == SQLDialect.MYSQL){
return function("utc_timestamp", SQLDataType.TIMESTAMP);
}
return function("current_timestamp", SQLDataType.TIMESTAMP);
}
}
请注意,您必须保留包名称org.jooq.impl。
然后在我的代码中我使用它:
InsertSetMoreStep<TableRecord> insert = db.insertInto(TABLE)
.set(TABLE.DATE,new Custom_MySQL_UTCTimestamp())
TABLE.DATE属于MySQL类型DATETIME
答案 1 :(得分:0)
您可以通过以下方式完成此操作:
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Madrid"));
long currentTime = calendar.getTimeInMillis();
然后使用JOOQ进入你的桌子:
dslContext.insertInto(MY_TABLE)
.set(MY_TABLE.MY_TIME, new Timestamp(currentTime))
.execute();
编辑:以上只会保存Chriki在下面的评论中提到的UTC时间。
但是,这可能有效:
long currentTime = calendar.getTimeInMillis() + TimeZone.getTimeZone("America/New_York").getOffset(Calendar.getInstance().getTimeInMillis())
https://www.tutorialspoint.com/java/util/timezone_getoffset_date.htm 基本上,找到UTC的偏移量,然后将其添加到当前的UTC时间。