MyBaits查询MySQL日期类型结果相差8个小时
问题描述
在Java项目中使用MyBatis作为ORM框架,但是查询出的MySQL日期类型字段值总是比数据库表里的值多8个小时。
具体说明:
MySQL数据库表字段类型为timestamp,映射的Java日期类型为java.util.Date,当数据库表里的字段值为2023-07-08 00:08:38时,查询出的Java字段值为2023-07-08 08:08:38。显然,查询结果的时间比表里实际存储的时间值大了8个小时。
原因分析
一开始以为是映射的Java日期类型不正确,修改为java.sql.Date依然不解决问题。
后来经过查询得知,造成查询结果与表值不一致的原因是:JDBC连接URL中设置的serverTimezone参数不正确导致。
错误的设置:jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC。
正确的设置:jdbc:mysql://127.0.0.1:3306/test?serverTimezone=Asia/Shanghai。
那么,在这里首先先解决的问题就是JDBC连接参数serverTimezone的作用是什么。
答案:serverTimezone参数用于设置对日期字段进行处理的时区,如果设定serverTimezone=UTC,会比中国时间早8个小时,如果在中国,可以选择Asia/Shanghai或者Asia/Hongkong。
追溯JDBC源码可以发现,在com.mysql.cj.mysqla.MysqlaSession类中有一个方法configureTimezone,专门用于处理时区的值。
// mysql-connector-java-6.0.6 源码解读
// 对应Maven依赖配置:
// <dependency>
// <groupId>mysql</groupId>
// <artifactId>mysql-connector-java</artifactId>
// <version>6.0.6</version>
// </dependency>
public void configureTimezone() {
// 从MySQL服务端读取时区变量配置,在MySQL上可以执行`show variables like '%time_zone%'`查询
String configuredTimeZoneOnServer = getServerVariable("time_zone");
if ("SYSTEM".equalsIgnoreCase(configuredTimeZoneOnServer)) {
configuredTimeZoneOnServer = getServerVariable("system_time_zone");
}
// 从JDBC连接参数`serverTimezone`中读取时区配置
String canonicalTimezone = getPropertySet().getStringReadableProperty(PropertyDefinitions.PNAME_serverTimezone).getValue();
if (configuredTimeZoneOnServer != null) {
// user can override this with driver properties, so don't detect if that's the case
if (canonicalTimezone == null || StringUtils.isEmptyOrWhitespaceOnly(canonicalTimezone)) {
try {
canonicalTimezone = TimeUtil.getCanonicalTimezone(configuredTimeZoneOnServer, getExceptionInterceptor());
} catch (IllegalArgumentException iae) {
throw ExceptionFactory.createException(WrongArgumentException.class, iae.getMessage(), getExceptionInterceptor());
}
}
}
if (canonicalTimezone != null && canonicalTimezone.length() > 0) {
// 如果JDBC连接参数serverTimezone明确配置了值,则使用该参数值作为时区设置
this.serverTimezoneTZ = TimeZone.getTimeZone(canonicalTimezone);
//
// The Calendar class has the behavior of mapping unknown timezones to 'GMT' instead of throwing an exception, so we must check for this...
//
if (!canonicalTimezone.equalsIgnoreCase("GMT") && this.serverTimezoneTZ.getID().equals("GMT")) {
throw ExceptionFactory.createException(WrongArgumentException.class, Messages.getString("Connection.9", new Object[] { canonicalTimezone }),
getExceptionInterceptor());
}
}
this.defaultTimeZone = this.serverTimezoneTZ;
}
【参考】
关于mysql的时区(下):如何设置mysql的时区
Mybatis查询Mysql datetime类型时,相差8小时 解决方案
MyBatis 处理 MySQL 时间类型 date 、datetime、timestamp
MyBaits查询MySQL日期类型结果相差8个小时的更多相关文章
- mysql 日期类型比较
MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型 存储空间 日期格式 日期范围 ------------ ------ ...
- 转 MySQL 日期类型详解
MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型 存储空间 日期格式 日期范围 ------------ ---- ...
- MySQL 日期类型及默认设置 (除timestamp类型外,系统不支持其它时间类型字段设置默认值)
MySQL 日期类型及默认设置 之前在用 MySQL 新建 table,创建日期类型列时遇到了一些问题,现在整理下来以供参考. MySQL 的日期类型如何设置当前时间为其默认值? 答:请使用 time ...
- java mysql 日期类型
mysql(版本:5.1.50)的时间日期类型如下: datetime 8bytes xxxx-xx-xx xx:xx:xx 1000-01-01 00:00:00到9999-12-31 23:59: ...
- Mysql日期类型大小比较---拉取给定时间段的记录
我们知道,mysql里边,日期类型有很多表现形式,date, datetime,timestamp等类型.考虑这样一种场景: 按时间段拉取给定时间段的内容,这时,我们就得使用日期类型的比较了. 表结构 ...
- mysql日期类型
日期类型 DATE TIME DATETIME TIMESTAMP YEAR 作用:存储用户注册时间,文章发布时间,员工入职时间,出生时间,过期时间等 YEAR YYYY(1901/2155) DAT ...
- mysql日期类型默认值'0000-00-00'容错处理
mysql日期默认值'0000-00-00'惹的祸 .net连mysql数据库时,如果表里有字段是日期型且值是‘0000-00-00’时,会报错.在C#里面日期不可能是那样的.或许是最小日期定义的差别 ...
- MySQL 日期类型函数及使用
1 MySQL 数据库中有五种与日期时间有关的数据类型,各种日期数据类型所占空间如下图所示: 2 datetime 与 date datetime 占用8字节,是占用空间最多的一种日期格式.它显示日期 ...
- LocalDateTime与mysql日期类型的交互(基于mybatis)
众所周知,在实体Entity里面,可以使用Java.sql.Date.java.sql.Timestamp.java.util.Date来映射到数据库的date.timestamp.datetime等 ...
- MySQL日期类型和毫秒值相互转换
有时需要将日期类型值转换成毫秒值,有时也要将毫秒值转换成日期,为了更方便,满足查询的需要. 现在,新建一张数据库表t_stu_info,并向表里插入数据 use test; show tables; ...
随机推荐
- ext4 扩容磁盘的方式方法
ext4 扩容磁盘的方式方法 背景 前期一直处理xfs,lvm磁盘的扩容 很少处理ext4的磁盘扩容 今天发现自己竟然对这一块有盲区. 晚上回家自己学习研究了会儿, 发现知识点还挺多 所以总结一下. ...
- [转帖]PostgreSQL 日志参数解释 常用环境日志参数配置
1.常用日志参数 logging_collector = on/off 是否将日志重定向至文件中,默认是off(该配置修改后,需要重启DB服务),启动之后查看进程ps -ef|grep postgr ...
- [转帖]关于winrm远程ps登录执行出现中文乱码和?乱码问题及其解决办法
https://segmentfault.com/a/1190000040566946?utm_source=sf-similar-article python的winrm库提供了命令行远程连接的功能 ...
- 基于Prometheus和Grafana监控redis,Oracle,mysql,pg以及sqlserver的方法总结
基于Prometheus和Grafana监控redis,Oracle,mysql,pg以及sqlserver的方法总结 简单记录一下方法 1.获取相应的exporter 1. redis docker ...
- selenium四种截图方式
1.get_screenshot_as_file() from selenium import webdriver driver = webdriver.Chrome() driver.get(&qu ...
- node使用nodemailer发送邮件
安装模块 npm install nodemailer 代码 const nodemailer = require('nodemailer'); // 查找到有关QQ邮箱的相关信息在 /node_mo ...
- hover时行级元素变成了块级元素,导致位置错乱
在hover时,i元素变成了块级元素: 导致这两个元素各自占了一行: 最终导致样式错乱: <div class="demo"> <!-- 添加图标 和 编辑图标 ...
- Centos7把home目录下多余的空间转移到/根目录下
通过df-h发现,根目录只有32G,而home目录可用的,居然有142G.我现在想分出70G给根目录 把你需要挂载的机器的逻辑卷记住(上面的图,左边是逻辑卷,右边是虚拟磁盘) /dev/mapper/ ...
- C# MVC+NHibernate 分页
一.页面代码,分为三部分,一是查询条件部分,二是数据部分,二是页码条 <div id="ticketoutquery"> <table> <tr> ...
- 手撕Vuex-添加全局$store
经过上一篇的介绍,了解到了 Vuex 的实现本质就是一个插件,所以要做的事情就是实现这个插件的代码编写即可. 本篇文章主要是实现一个全局的 $store,这个 $store 是挂载在 Vue 的原型上 ...