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

连接初始化的过程

  1. ConnectionImpl#1978 "配置时区"
  2. ConnectionImpl#705 将当前时区保存到了数据库连接中

读取的过程

  1. MyBatis的各个TypeHandler
  2. ByteArrayRow#63 拿到字节数组
  3. ResultSetRow#705 将字节数组转为字符串
  4. ResultSetImpl#5729 将字符串分离为年月日时分秒
  5. ResultSetImpl#5873 对应上文01.5.2
  6. ResultSetImpl#5877 对应上文01.4.2和01.4.3
  7. ResultSetImpl#5317 如果Java要返回的是String, 则会在这里将时间戳转为jvm当前时区下的年月日时分秒

版本8.0

  1. NativeProtocol#2147#2158 保存"配置时区"
  2. ByteArrayRow#89 拿到数据库返回的字节, 大致相当于 01.5.1的ByteArrayRow#63
  3. MysqlTextValueDecoder#338 解析字节数组, 拿到年月日时分秒并封装为InternalTimestamp
  4. SqlTimestampValueFactory#100 也就是上文02.3
  5. StringValueFactory#94 如果Java要返回的是String, 就直接将InternalTimestamp转为字符串, 不考虑当前系统时区了, 与5.1的第7条有区别
  6. AbstractResultSetRow#78
  7. 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的更多相关文章

  1. Mysql时间戳转Java时间戳

    MySQL 时间戳和Java返回的时间戳是不一样的 例如: 当前时间是 2014-08-04 10:42:55.204000 使用mysql时间戳函数UNIX_TIMESTAMP 返回的结果为: 14 ...

  2. java和mysql之间的时间日期类型传递

    摘自:http://blog.csdn.net/weinianjie1/article/details/6310770 MySQL(版本:5.1.50)的时间日期类型如下: datetime 8byt ...

  3. 理解Java中的引用传递和值传递

    关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天学习 ...

  4. 利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包含增删改查、JavaBean反射原理,附源码)

    最近看老罗的视频,跟着完成了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完成对数据库的增删改查.其中查询这块,包括普通的查询和利用反射完成的查询,主要包括以下几个函数接口 ...

  5. FROM_UNIXTIME 格式化MYSQL时间戳函数

    FROM_UNIXTIME 格式化MYSQL时间戳函数 对MYSQL没有进行过深入的研究,基础知识匮乏,一遇到问题只能手册,看来要把MYSQL的学习安排进时间表了. 函数:FROM_UNIXTIME作 ...

  6. Java连接MySQL数据库及简单操作代码

    1.Java连接MySQL数据库 Java连接MySql需要下载JDBC驱动MySQL-connector-java-5.0.5.zip(举例,现有新版本).然后将其解压缩到任一目录.我是解压到D盘, ...

  7. Java网页数据采集器[中篇-数据存储]【转载】

    本期概述 上期我们学习了html页面的数据采集,为了方便我们今后来调用收集到的数据,首先我们需要学习下如何将这些采集到的数据存储起来(MySql数据库). 数据采集页面 2011-2012赛季英超球队 ...

  8. 转载:Java连接MySQL 数据库的正确操作流程

    转载网址:http://www.bitscn.com/pdb/mysql/201005/186551.html       以下的文章主要介绍的是Java连接MySQL 数据库(以MySQL数据库为例 ...

  9. 利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包括增删改查、JavaBean反射原理,附源代码)

    近期看老罗的视频,跟着完毕了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完毕对数据库的增删改查.当中查询这块,包含普通的查询和利用反射完毕的查询,主要包含以下几个函数接口 ...

随机推荐

  1. k8s-日志收集架构

    日志收集 Kubernetes 集群中监控系统的搭建,除了对集群的监控报警之外,还有一项运维工作是非常重要的,那就是日志的收集. 介绍 应用程序和系统日志可以帮助我们了解集群内部的运行情况,日志对于我 ...

  2. BurpSuite 爆破网页后台登陆

    由于 Burp Suite是由Java语言编写而成,所以你需要首先安装JAVA的运行环境,而Java自身的跨平台性,使得软件几乎可以在任何平台上使用.Burp Suite不像其他的自动化测试工具,它需 ...

  3. 移动端测试之APP安全测试

    现在APP测试已经是测试行业的一个重要分支,对APP测试技能和经验的要求也越来越高,看到一篇关于APP安全测试的总结,分享给需要的朋友.1.软件权限1)扣费风险:包括发送短信.拨打电话.连接网络等2) ...

  4. Win10环境下,告别MarkdownPad,用Notepad++搭建编写md文档的环境

    1. 为什么抛弃MarkdownPad 2 ? MarkdownPad坊间号称 Windows 环境下最好用的markdown编辑器-EXO me??? 博主入MarkdownPad 2 坑就是因为这 ...

  5. NetCore2.x 使用Log4Net(一)

    前言:本章仅仅是Log4Net的基本简单的运用,后续章节会按照我的项目使用情况进行深入研究 1.项目搭建 新建一个基于.netCore2.x的Web项目          =>   过程略 给新 ...

  6. 使用2种python脚本工具将2个txt文档中的文字进行比较,并计算出Corr, WER正确率,准确率

    一.准备: linux服务器,src2mlf.py   rec2mlf.py   HResults文件,1份源文件和1份需要对比的文件.文件放置于本人云盘 二.使用方法: 1. 对比工具 HResul ...

  7. 7.使用EXPLAIN 来分析SQL和表结构_1

    explain:查看执行计划 使用explain 关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的 分析你的查询语句或是表结构的性能瓶颈 使用explain 可以获 ...

  8. Image Processing and Analysis_8_Edge Detection:Multiresolution edge detection techniques ——1995

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  9. PhpStorm添加PHP代码规范检查CodeSniffer(phpcs)和PHP代码静态分析工具Mess Detector(phpmd)

    一.安装 添加镜像,加速下载 ./composer.phar  config -g repo.packagist composer https://packagist.phpcomposer.com ...

  10. linux操作系统中的常用命令以及快捷键(一)

    接触了linux系统一年,总结一些常用的命令,快捷键等一些尝试 1.首先查看linux内核数量,常用于编译源码包时 用 make -j 来指定内核数来编译 grep ^processor /proc/ ...