一次 Jar 包升级引发的血案 amp; 解决
本文阅读时间大约6分钟。
写在前面
最近工作中遇到两例mysql时间戳相关的问题,一个是mysql-connector-java和msyql的精度不一致导致数据查不到;另一例是应用服务器时区错误导致数据查询不到。
通过这篇文章,希望能够解答关于mysql中时间戳的几个问题:
mysql中的DATETIME精度为什么只支持到秒?
mysql中的DATETIME类型跟时区有关吗?
mysql设计表的时候,表示时间的字段改如何选择?
案例分析:DATETIME的精度问题
前段时间,将负责的应用的mysql-connector-java的版本从5.1.16升级到5.1.30,在做功能回归的时候发现,使用了类似上面的SQL的用例的运行时数据会有遗漏,导致功能有问题。
考虑到我负责的应用中,有个功能需要用到类似下面这种SQL,即使用时间戳作为查询的条件,查询在某个时间戳之后的所有数据。
经过排查发现:mysql-connector-java在5.1.23之前会将秒后面的精度丢弃再传给MySQL服务端,正好我们使用的mysql版本中DATETIME的精度是秒;在我将mysql-connector-java升级到5.1.30后,从java应用通过mysql-connector-java将时间戳传到MySQL服务端的时候,就不会将毫秒数丢弃了,从mysql-connector-java的角度看是修复了一个BUG,但是对于我的应用来说却是触发了一个BUG。
如果你面对这个问题,你会怎么修复呢?
我们当时想了三种方案:
将mybatis的Mapper接口中的时间戳参数的类型,从java.util.Date改成java.sql.Date;
在传入Mapper接口之前,将传入的时间戳按秒取正,代码如下
在查询之前,将传入的时间戳减1秒;
经过验证,方案1会,java.util.Date转过去的java.sql.Date对象会将日期之后的精度全部丢掉,从而导致查询出更多不必要的数据;方案3是可以的,就是可能会查出多一两条数据;方案2也是可以的,相当于从代码上对mysql-connector-java的特性做了补偿。最终我选择的是方案2。
案例复现
利用homebrew安装MySQL,版本是8.0.15,装好后建一个表,用来存放用户信息,SQL如下:
使用spirngboot + mybatis作为开发框架,定义一个用户实体,代码如下所示:
定义该实体对应的Mapper,代码如下:
设置连接mysql相关的配置,代码如下:
编写测试代码,先插入一条数据,然后用时间戳作为查询条件去查询,代码如下:
运行单测,如我们的设想,确实是没有查询出数据来,结果如下:
然后修改代码,利用上面的代码将查询的时间戳按秒取正,代码如下:
再次运行单测,如我们的设想,这次可以查询出数据来了。
不过,这里有个小插曲,我在最开始设计表的时候,使用的SQL语句是下面这样的:
你一定发现了,这里的datetime已经支持小数点后更小的时间精度了,最多支持6位即最多可以支持到微妙级别。这个特性是什么时候引入的呢,我去查阅了MySQL的官方文档(https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html),发现这个特性是在mysql 5.6.4之后开始支持的。
知识点总结
经过了前面的实际案例分析和案例复现,想必读者已经对mysql中DATETIME这个类型有了一定的认识,接下来跟我一起看下,我们从这个案例中可以总结出哪些经验。
mysql-connector-java的版本和mysql的版本需要配套使用,例如5.6.4之前的版本,就最好不要使用mysql-connector-java的5.1.23之后的版本,否则就可能会遇到我们这次遇到的问题。
MySQL中用来表示时间的字段类型有:DATE、DATETIME、TIMESTAMP,它们之间有相同点,各自也有自己的特性,我总结了一个表格,如下所示:
DATETIME类型在MySQL中是以“YYYYMMDDHHMMSS”格式的整数存放的,与时区无关,使用8个字节的空间;
TIMESTAMP类型可以保存的时间范围要小很多,显示的值依赖时区,MySQL的服务器、操作系统以及客户端连接都有时区的设置。
一般情况下推荐使用DATETIME作为时间戳字段,不推荐使用bigint类型来存储时间。
在开发中,应该尽量避免使用时间戳作为查询条件,如果必须要用,则需要充分考虑MySQL的精度和查询参数的精度等问题。
参考资料
https://dev.mysql.com/doc/refman/8.0/en/datetime.html
《高性能MySQL》
热门内容:
如何优雅的导出 Excel
JDK 13 新特性一览
某小公司RESTful、共用接口、前后端分离、接口约定的实践
请停止学习框架
IntelliJ IDEA 2019.3这回真的要飞起来了,新特性抢先看!
想不到!面试官问我:Redis 内存满了怎么办?
用了这么久 IDEA,你竟然不知道有个功能叫自动补全!
5 门可能衰落的编程语言
优秀的 Java 项目代码都是如何分层的?
最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ♡
一次 Jar 包升级引发的血案 amp; 解决相关推荐
- Jar 包依赖冲突排查思路和解决方法(logback + slf4j-log4j12)
Jar 包依赖冲突排查思路和解决方法 [TOC] 起因 喜大普奔,本期发布中,我们的应用从 jdk7 升级到 jdk8,终于可以用上新特性的语法进行代码编写,通过几轮开发.测试和验证后,在上预发环境时 ...
- Log4j2 日志 依赖 jar包 缺失 导致启动报错 解决方法
Log4j2 日志 依赖 jar包 缺失 导致启动报错 解决方法. 一个Java老项目,更新了日志工具,升级为Log4j2,在引入log4j-api-2.14.0.jar 和log4j-core-2. ...
- POI版本对比jar包升级后代码报错修正
学习目标: 最近使用EasyExcel写导入导出Excel,需要POI版本是3.17,之前是3.9,必须升级jar包,升级之后发现很多代码报错,需要修改调整,以下用于记录调整的代码. 颜色定义变化 旧 ...
- jar包升级部署到服务器详细流程,将服务部署在linux中
假设你已经准备好以下东西,即可进行服务部署 一台服务器(云服务器或虚拟机皆可) 已安装好的jdk 1.8 + 的环境(可自行百度) 打好的jar包(maven打jar包) 1. 在服务器中新建好你的项 ...
- Jar 包依赖冲突排查思路和解决方法
作者:jingQ https://www.sevenyuan.cn/ 起因 应用从 jdk7 升级到 jdk8,终于可以用上新特性的语法进行代码编写,通过几轮开发.测试和验证后,在上预发环境时,应用突 ...
- maven jar包冲突常见报错及解决方法
见到如下错误,可以想到是不是jar包冲突 1.java.lang.NoSuchMethodError 2.java.lang.ClassNotFoundException 3.java.lang.No ...
- was服务器里面jar包_如何在was中解决jar包冲突
如何在 was 中解决 jar 包冲突 大型的基于 WebSphere 的项目开发中,同一个 WebSphere Application Server (以下 简称 WAS ) 上会部署多个应用程序, ...
- android 混淆不混淆第三方jar,Android 第三方Jar包FastJson 代码混淆时的解决方法 - Android开发论坛 - 51CTO技术论坛_中国领先的IT技术社区...
我们做AndroidApp软件的时候,经常会对App进行签名打包和代码混淆,在工程中没有使用第三方Jar文件的时候不用考虑很多因素,现在要说的是当你在你的工程使用使用了FastJson这个快速解析Js ...
- java win10窗口启动假死_window执行jar包会出现假死现象解决
windows jar包启动的几种方式介绍 java -jar xxx.jar(jar包的路径),最普通简单的方式,通过windows的命令行窗口启动,并在命令行窗口运行,输出.可以在启动的时候增加参 ...
最新文章
- 【java基础】map的基本使用与字符串中每个字符出现的次数统计
- Java Servlet 开发常用代码、模板、问题
- [Python图像处理] 三十六.OpenCV图像几何变换万字详解(平移缩放旋转、镜像仿射透视)
- 第七章:项目成本管理
- mysql的中文乱码url,MySQL 中文显示乱码
- python time智能等待_Python Selenium智能等待
- java中bash应用_在bash脚本中查找java应用程序的进程ID(以查看目标应用程序是否已在运行)...
- HttpClient4.3.x的连接管理
- 史上最详细的JNI入门教程HelloNative
- Delaunay三角剖分算法
- 在Flex4中嵌入字体
- countifs函数怎么用,excel函数的操作步骤
- 记一次quartz定时任务不执行排雷
- windows的文件路径文件(夹)名的分割符也可以用正斜杠
- ADO 从ACCESS数据库读取图片并显示出来
- 微型计算机基础学的什么,微型计算机操作基础课的教学
- ad被锁定的账户_如何在AD中方便查询被锁定的帐号状态和特定条件的查询被锁定的帐号...
- 3.2 使用直线段工具标注尺寸信息 [Illustrator CC教程]
- matlab 拉布拉斯矩阵,关于图像处理:C ++中的拉普拉斯矩阵计算
- 图文细说11种计算机图标符号的历史