我有一个Java应用程序,它将一些数据插入到我的mysql数据库中。到目前为止,我已经通过Java代码从客户端计算机获取了时间戳:
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date insertDate= new Date();
,然后在我准备好的语句中使用它,例如
update 'table'set (status,insertDate) values (?,?)
pst.setString(1, "Success");
pst.setString(2, dateFormat.format(insertDate));
这工作正常,但是如果其中一个客户端弄乱了系统时间并将其设置为一天,那该怎么办?因此,我想将服务器的时间戳记作为基本事实(发生插入操作的实际时间),发现我可以使用NOW()了。我更改了代码,现在看起来像这样
update 'table' set (status,insertDate) values (?,NOW())
pst.setString(1, "Success");
这是完成这项工作的正确方法吗?我假设这将插入请求到达服务器并发生插入时的时间戳,而不是直接从客户端获取timstamp。我的理解正确吗?
答案 0 :(得分:0)
如果要在插入数据库时捕获当前时刻,最好的方法当然是在服务器上捕获该时刻。您可以比最终用户更信任服务器系统管理员,以保持计算机时钟的正确设置。
提示:通常,最好将可以将所有工作从应用程序移至数据库服务器,如果您具有功能强大的强大数据库服务器。
DEFAULT CURRENT_TIMESTAMP
更好,自动化。无需始终将current-moment-capture写入SQL事务代码中。
相反,应在服务器上定义一个DEFAULT
值,作为定义表和列的一部分。
根据this doc,函数 CURRENT_TIMESTAMP
是标准SQL ,用于捕获从服务器时钟读取的当前事务开始时的当前时刻。我不知道使用标准SQL命令来捕获语句执行期间的当前时刻(与事务开始相反)。
当前时刻应存储在类似于标准SQL类型TIMESTAMP WITH TIME ZONE
的数据类型的列中。
此代码可能与标准SQL相似,并且可以在诸如Postgres之类的数据库中使用。
CREATE TABLE Person (
pkey_ INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
surname_ VARCHAR(80) NOT NULL ,
given_name_ VARCHAR(80) NOT NULL ,
row_inserted_ TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
) ;
关于MySQL:
TIMESTAMP WITH TIME ZONE
为TIMESTAMP
。 GENERATED…
功能,因此请使用AUTO_INCREMENT
。 CURRENT_TIMESTAMP
。这是Question代码中特定于MySQL的NOW()
函数的同义词。我建议在可行的情况下都遵守标准。(我不使用MySQL,因此请验证详细信息。)
MySQL示例:
CREATE TABLE Person (
pkey_ INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
surname_ VARCHAR(80) NOT NULL ,
given_name_ VARCHAR(80) NOT NULL ,
row_inserted_ TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ;
将自动插入的值作为OffsetDateTime
对象检索。
OffsetDateTime odt = myResultSet.get( "row_inserted_" , OffsetDateTime.class ) ;
看到那一刻是在特定地区(时区)的人们使用的挂钟时间而不是UTC中看到的。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.withZoneSameInstant( z ) ;