JDBC連接時(shí)有個(gè)TimeZone配置,這玩意到底有用嗎?我是使用Postgresql和Mysql兩個(gè)數(shù)據(jù)庫(kù)驗(yàn)證的。結(jié)果如下:
數(shù)據(jù)庫(kù) | 部署方式 | 版本 | JDBC連接TimeZone參數(shù) | JDBC連接serverTimezone參數(shù) | 總結(jié) |
Mysql | docker | 8.0 | 沒(méi)用 | 有用,會(huì)使用客戶端時(shí)區(qū)與設(shè)置的參數(shù)時(shí)區(qū)比較,并返回客戶端時(shí)區(qū)對(duì)應(yīng)的時(shí)間,詳見(jiàn)實(shí)例1 | Mysql使用JDBC連接時(shí)可以配置serverTimezone參數(shù)告訴客戶端服務(wù)器的時(shí)區(qū),因?yàn)镸ysql的TimeStamp類型是沒(méi)有時(shí)區(qū)概念的,且沒(méi)有timestamp with time zone數(shù)據(jù)類型,只能通過(guò)連接時(shí)配置數(shù)據(jù)庫(kù)server的時(shí)區(qū),并通過(guò)兩時(shí)區(qū)的對(duì)比,返回正確的客戶端時(shí)區(qū)的時(shí)間 |
Postgresql | docker | 15.3 | 沒(méi)用 | 沒(méi)用 | Postgresql使用JDBC連接時(shí),時(shí)區(qū)參數(shù)均無(wú)效,但Postgresql有timestamp with time zone數(shù)據(jù)類型,使用該數(shù)據(jù)類型時(shí)不管數(shù)據(jù)庫(kù)是什么時(shí)區(qū)設(shè)置,也不管客戶端是什么時(shí)區(qū)設(shè)置,只要你的客戶端時(shí)區(qū)不變,你存取得到的都是同一個(gè)時(shí)間,該時(shí)間的時(shí)區(qū)取決于客戶端的時(shí)區(qū)。數(shù)據(jù)庫(kù)中存儲(chǔ)的是對(duì)應(yīng)的UTC時(shí)區(qū)時(shí)間,比如:2023-05-24 00:51:24.578703 +00:00,詳見(jiàn)實(shí)例2 |
?文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-457080.html
實(shí)例1:
使用Mysql數(shù)據(jù)庫(kù),建表DDL如下:
create table test ( a int null, b timestamp null );
數(shù)據(jù)庫(kù)中存儲(chǔ)的數(shù)據(jù):
?使用JDBC連接,不配置serverTimezone參數(shù),客戶端時(shí)區(qū)為東八區(qū),執(zhí)行以下SQL并用Java Date類型接收輸出:
SELECT b FROM test WHERE a = 1; SELECT now();
輸出結(jié)果,注意Java的Date類型本身是沒(méi)有時(shí)區(qū)屬性的,這里之所以輸出了CST可以自行研究Date的toString方法:
Tue May 23 15:13:46 CST 2023 Wed May 24 01:11:17 CST 2023
使用JDBC連接,配置serverTimezone參數(shù)為serverTimezone=UTC,客戶端時(shí)區(qū)為東八區(qū),執(zhí)行上面的SQL并用Java Date類型接收輸出:
Tue May 23 23:13:46 CST 2023 Wed May 24 09:12:52 CST 2023
總結(jié):
當(dāng)不使用serverTimezone配置時(shí),JDBC連接中服務(wù)器時(shí)區(qū)被認(rèn)為與客戶端時(shí)區(qū)相同,因此數(shù)據(jù)庫(kù)中存儲(chǔ)的時(shí)間返回時(shí)被認(rèn)為是東八區(qū)時(shí)間,無(wú)需變動(dòng),但SELECT now();返回的是Mysql服務(wù)器時(shí)間,即UTC時(shí)間。配置serverTimezone參數(shù)后,JDBC連接中服務(wù)器時(shí)區(qū)為UTC,客戶端時(shí)區(qū)為東八區(qū),查詢數(shù)據(jù)庫(kù)中時(shí)間被認(rèn)為是UTC時(shí)間,返回給客戶端時(shí)進(jìn)行+8小時(shí)操作,同時(shí)SELECT now();返回值經(jīng)過(guò)時(shí)區(qū)轉(zhuǎn)換,正確的返回了東八區(qū)時(shí)間。
?
實(shí)例2:
使用Postgresql數(shù)據(jù)庫(kù),建表DDL如下:
create table test ( a integer, b timestamp with time zone );
客戶端時(shí)區(qū)為東八區(qū),分別執(zhí)行以下SQL:
INSERT INTO test VALUES (2, now()); SELECT b FROM test WHERE a = 2; SELECT now();
查詢結(jié)果如下:
Wed May 24 09:39:39 CST 2023 Wed May 24 09:39:39 CST 2023
數(shù)據(jù)庫(kù)中存儲(chǔ)結(jié)果:
修改客戶端時(shí)區(qū)為東九區(qū),重新執(zhí)行以上SQL:
Wed May 24 10:42:17 KST 2023 Wed May 24 10:42:17 KST 2023
數(shù)據(jù)庫(kù)中存儲(chǔ)結(jié)果:
總結(jié):
使用Postgresql的timestamp with time zone數(shù)據(jù)類型時(shí),不管數(shù)據(jù)庫(kù)是什么時(shí)區(qū)設(shè)置,也不管客戶端是什么時(shí)區(qū)設(shè)置,只要你的客戶端時(shí)區(qū)不變,你存取得到的都是同一個(gè)時(shí)間,該時(shí)間的時(shí)區(qū)取決于客戶端的時(shí)區(qū)。數(shù)據(jù)庫(kù)中存儲(chǔ)的是轉(zhuǎn)換后的UTC時(shí)間。
?
綜上:
使用Mysql時(shí),JDBC連接中應(yīng)正確配置serverTimezone參數(shù);使用Postgresql時(shí),使用timestamp with time zone數(shù)據(jù)類型。來(lái)保證獲取時(shí)間時(shí)時(shí)區(qū)的正確性。
另外,建議能不用數(shù)據(jù)庫(kù)的now()就別用了,數(shù)據(jù)庫(kù)時(shí)區(qū)會(huì)搞得你頭疼;更近一步,能別用時(shí)間(Date)就別用了,時(shí)間戳沒(méi)有時(shí)區(qū)的概念,當(dāng)前端需要顯示的時(shí)候再通過(guò)DateFormat或Json轉(zhuǎn)換配置時(shí)區(qū)即可,可以省去很多需要考慮時(shí)區(qū)的工作。
?
以上是我自己的實(shí)驗(yàn)結(jié)果,如果你有不同的結(jié)論,歡迎一起探討。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-457080.html
到了這里,關(guān)于【數(shù)據(jù)庫(kù)】時(shí)區(qū)及JDBC的時(shí)區(qū)設(shè)置的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!