0078 Java与MySQL时间戳传递/存储/协调问题--userLegacyDatetimeCode--userTimezone--serverTimezone
00. 基本问题
0.0 版本: 驱动5.1.47和8.0.17
0.1 MySQL驱动5.1有userLegacyDatetimeCode和userTimezone两个参数, 8.0没有
0.2 Java与MySQL间传递时间戳的时候, 传递的是年月日时分秒, 没有时区
0.3 MySQL传递回来的是: MySQL读取到底层存储的时间戳, 按照当前连接(MySQL侧)的时区转为年月日时分秒
0.4 但是, 两个系统时区可能会不同, userLegacyDatetimeCode和userTimezone就是用来协调时区的
01. MySQL驱动5.1
1.1 数据库连接在建立时, 会创建一个Calendar对象保存在连接中, 其中保存了连接创建时的时区, 即下文的"连接时区". 见ConnectionImpl#705
1.2 如果配置了serverTimezone,则会将其保存到连接中, 即下文的"配置时区". 见ConnectionImpl#1978
1.3 userLegacyDatetimeCod=true&userTimezone=false, 这是默认情况
1.3.1 此时对应Java和MySQL时区相同
1.3.2 Java接收到MySQL传递来的年月日时分秒, 加上"连接时区"创建时间戳java.sql.Timestamp, 见ResultSetImpl#5877和TimeUtil#369
1.4 userLegacyDatetimeCod=true&userTimezone=true&serverTimezone=GMT%2B6
1.4.0 userTimezone=true, 必须在userLegacyDatetimeCod=true时才有效
1.4.1 此时对应二者时区不同
1.4.2 与3.2相同, 先将年月日时分秒+"连接时区", 创建时间戳
1.4.3 再进行时区调整, 调整为"配置时区". 见ResultSetImpl#5877和TimeUtil#160
1.5 userLegacyDatetimeCod=false&serverTimezone=GMT%2B6
1.5.1 此时对应二者时区不同
1.5.2 将年月日时分秒+"配置时区"创建时间戳. 见ResultSetImpl#5874
1.5.3 这也是8.0的处理方式
02. MySQL驱动8.0
2.1 8.0没有userLegacyDatetimeCode和userTimezone两个参数
2.2 一定要配置serverTimezone为MySQL运行的时区. 连接建立时会将这个时区存储到连接中. 见NativeProtocol#2147#2158
2.3 将年月日时分秒+"配置时区"构造时间戳. 见SqlTimestampValueFactory#100. 这里的cal就是在#68根据"配置时区"创建的
03. 代码跟踪中的一些关键点
版本5.1
连接初始化的过程
- ConnectionImpl#1978 "配置时区"
- ConnectionImpl#705 将当前时区保存到了数据库连接中
读取的过程
- MyBatis的各个TypeHandler
- ByteArrayRow#63 拿到字节数组
- ResultSetRow#705 将字节数组转为字符串
- ResultSetImpl#5729 将字符串分离为年月日时分秒
- ResultSetImpl#5873 对应上文01.5.2
- ResultSetImpl#5877 对应上文01.4.2和01.4.3
- ResultSetImpl#5317 如果Java要返回的是String, 则会在这里将时间戳转为jvm当前时区下的年月日时分秒
版本8.0
- NativeProtocol#2147#2158 保存"配置时区"
- ByteArrayRow#89 拿到数据库返回的字节, 大致相当于 01.5.1的ByteArrayRow#63
- MysqlTextValueDecoder#338 解析字节数组, 拿到年月日时分秒并封装为InternalTimestamp
- SqlTimestampValueFactory#100 也就是上文02.3
- StringValueFactory#94 如果Java要返回的是String, 就直接将InternalTimestamp转为字符串, 不考虑当前系统时区了, 与5.1的第7条有区别
- AbstractResultSetRow#78
- PropertyKey jdbc url的property的key枚举类, https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-configuration-properties.html
04. The server time zone value '???DZ?ʱ?' is unrecognized or represents more than one time zone 异常是怎么回事?
在三种情况下会抛出
上文01.4/01.5/02.2情况下未配置serverTimezone是都会抛出
因为, NativeProtocol#2130或者ConnectionImpl#1960拿到数据库的system_time_zone是乱码, 也就是select @@system_time_zone 的值
所以要配置serverTimezone为数据库运行的时区
05. 问题
时间戳传递为什么不是一个数字形式的秒/毫秒呢, 而是一个没有时区的年月日时分秒呢? 还得协调时区, 多复杂呢?
0078 Java与MySQL时间戳传递/存储/协调问题--userLegacyDatetimeCode--userTimezone--serverTimezone的更多相关文章
- Mysql时间戳转Java时间戳
MySQL 时间戳和Java返回的时间戳是不一样的 例如: 当前时间是 2014-08-04 10:42:55.204000 使用mysql时间戳函数UNIX_TIMESTAMP 返回的结果为: 14 ...
- java和mysql之间的时间日期类型传递
摘自:http://blog.csdn.net/weinianjie1/article/details/6310770 MySQL(版本:5.1.50)的时间日期类型如下: datetime 8byt ...
- 理解Java中的引用传递和值传递
关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习 ...
- 利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包含增删改查、JavaBean反射原理,附源码)
最近看老罗的视频,跟着完成了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完成对数据库的增删改查.其中查询这块,包括普通的查询和利用反射完成的查询,主要包括以下几个函数接口 ...
- FROM_UNIXTIME 格式化MYSQL时间戳函数
FROM_UNIXTIME 格式化MYSQL时间戳函数 对MYSQL没有进行过深入的研究,基础知识匮乏,一遇到问题只能手册,看来要把MYSQL的学习安排进时间表了. 函数:FROM_UNIXTIME作 ...
- Java连接MySQL数据库及简单操作代码
1.Java连接MySQL数据库 Java连接MySql需要下载JDBC驱动MySQL-connector-java-5.0.5.zip(举例,现有新版本).然后将其解压缩到任一目录.我是解压到D盘, ...
- Java网页数据采集器[中篇-数据存储]【转载】
本期概述 上期我们学习了html页面的数据采集,为了方便我们今后来调用收集到的数据,首先我们需要学习下如何将这些采集到的数据存储起来(MySql数据库). 数据采集页面 2011-2012赛季英超球队 ...
- 转载:Java连接MySQL 数据库的正确操作流程
转载网址:http://www.bitscn.com/pdb/mysql/201005/186551.html 以下的文章主要介绍的是Java连接MySQL 数据库(以MySQL数据库为例 ...
- 利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包括增删改查、JavaBean反射原理,附源代码)
近期看老罗的视频,跟着完毕了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完毕对数据库的增删改查.当中查询这块,包含普通的查询和利用反射完毕的查询,主要包含以下几个函数接口 ...
随机推荐
- NIO总结-----Buffer
Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...
- 前端工程师应该知道的yarn知识
yarn 是在工作中离不开的工具,但在工作中,很多人基本只会使用 yarn install,而且会手动删除 node-modules,或删除 yarn.lock 文件等不规范操作.本文将从一些基础的知 ...
- SpringBoot 异步调用方法并接收返回值
项目中肯定会遇到异步调用其他方法的场景,比如有个计算过程,需要计算很多个指标的值,但是每个指标计算的效率快慢不同,如果采用同步执行的方式,运行这一个过程的时间是计算所有指标的时间之和.比如: 方法A: ...
- js的一些兼容融性问题
1.非行内样式获取 高级浏览器 getComputedStyle(obox.false)//获取所有属性 ie浏览器 box.currentStyle//获取所有属性 兼容写法 function ge ...
- oracle wm_concat函数用法
在Oracle中使用wm_concat(column)可以实现字段的分组合并,逗号分隔.
- C++ STL 之 map
#include <iostream> #include <map> using namespace std; // map构造函数 // map<T1, T2> ...
- Outline 科学的上网
outline 官网:https://getoutline.org/zh-CN/home 下载 Outline 管理器 下载 Outline 客户端 配置浏览器代理
- redis----Not only Sql 理论
数据存储的瓶颈:(mysql ==>500万数据就已经很慢了) 1 数据量的总大小,一个机器放不下时 2 数据 的索引,一个机器的内存放不下时 3 访问量(读写混合),一个实例不能承受 Redi ...
- Djnago模板与标签
1.模版系统 基本语法 {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 在Django的模板语言中按此语法使用:{{ 变量名 }}. python基础的基本数据类型可以通 ...
- 在DjangoAdmin中使用KindEditor(上传图片)
一.下载 http://kindeditor.net/down.php 删除asp.asp.net.php.jsp.examples文件夹 拷贝到static目录下 二.配置 kindeditor目录 ...