相信99%的朋友都没有注意到的数据库时间类型的问题

文章目录

  • 创建表SQL
  • 实例小测试
  • 知识点小测试
  • 可以怎样处理
  • 只有查询有问题吗?
  • MySQL时间

很多时候,程序运行起来没有问题,并不代表程序就精确,例如创建时间多一秒少一秒这种事情,很多时候是没有人注意到这个问题。

当然,关于创建时间多一秒少一秒本身可能有不太重要,但是关于时间的查询,绝对就是一个比较严重的问题了。

有时候数据特殊性导致很难发现多一条少一条很难发现,但是少一条数据可能就是非常严重的问题。

本文,以MySQL和MyBatis为例,来说一下其中的关于时间的一些非常容易被忽略的小问题。

创建表SQL

create table datetime_timestamp (
  id int(20) unsigned not null auto_increment COMMENT '主键ID',
  datetime0 datetime COMMENT '没有小数部分,支持到秒',
  datetime3 datetime(3) COMMENT '3位小数,毫秒',
  datetime6 datetime(6) COMMENT '6位小数,微妙',
  timestamp0 TIMESTAMP COMMENT '没有小数部分,支持到秒',
  timestamp3 TIMESTAMP(3) COMMENT '3位小数,毫秒',
  timestamp6 TIMESTAMP(6) COMMENT '6位小数,微妙',
  primary key (`id`)
) engine = InnoDB auto_increment = 1 default CHARSET = utf8mb4 collate = utf8mb4_unicode_ci COMMENT = '时间';

实例小测试

// select * from datetime_timestamp where datetime0 = #{date}
// datetime0的数据类型是MySQL datetime
// DatetimeTimestampMapper datetimeTimestampMapper
List<DatetimeTimestampTO> listDatetime0ByDate(java.util.Date date);
@Resource
private DatetimeTimestampMapper datetimeTimestampMapper;

@Test
void listDatetime0ByDate() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.YEAR, 2023);
    calendar.set(Calendar.MONTH, 11);
    calendar.set(Calendar.DATE, 31);
    calendar.set(Calendar.HOUR_OF_DAY, 12);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    Date date = calendar.getTime();
    List<DatetimeTimestampTO> tos = datetimeTimestampMapper.listDatetime0ByDate(date);
    tos.forEach(System.out::println);
}

在这里插入图片描述

上面的数据查询能查询到id为5的那一条数据吗?

产生这种结果的原因是什么?

答案是:极小概率能查到

为什么呢?

知识点小测试

要知道上面问题的答案,得先搞清楚另一个问题:

java.util.Date类型和MySQL的datetime类型绝对匹配吗?

答案是不能,java.util.Date精度是毫秒,datetime默认是datetime(0),精度是秒。

select * from datetime_timestamp where datetime0 = #{date}

显然只有当java.util.Date的毫秒为0的时候才能匹配上。

我们可以看一下,MyBatis打印的SQL:

在这里插入图片描述

我们可以看到MyBatis将java.util.Date被转换为了java.sql.Timestamp

为什么会这样呢?

因为java.sql.PreparedStatement不支持java.util.Date,只支持java.sql.Date:
setDate

执行转换的是org.apache.ibatis.type.DateTypeHandler:

DateTypeHandler

可以怎样处理

将毫秒部分设置为0,就可以
calendar.set(Calendar.MILLISECOND, 0);

@Resource
private DatetimeTimestampMapper datetimeTimestampMapper;

@Test
void listDatetime0ByDate() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.YEAR, 2023);
    calendar.set(Calendar.MONTH, 11);
    calendar.set(Calendar.DATE, 31);
    calendar.set(Calendar.HOUR_OF_DAY, 12);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    Date date = calendar.getTime();
    List<DatetimeTimestampTO> tos = datetimeTimestampMapper.listDatetime0ByDate(date);
    tos.forEach(System.out::println);
}

为啥我们查询基本很少发现时间查询有问题呢?

因为很多时候,时间更多的时候是查询的范围,要么就是查询到日期,不涉及到时间毫秒、微妙这种。

只有查询有问题吗?

不是,插入也有问题,插入的时候,如果大于等于500毫秒,会向前进1,小于500毫秒会被舍弃:
毫秒截断问题

有兴趣的朋友,可以自己动手尝试一下这个。

MySQL时间

MySQL的TIME、DATETIME、TIMESTAMP支持小数秒,最高精度能到微妙(6为小数)

  • TIME(fsp)
  • DATETIME(fsp)
  • TIMESTAMP(fsp)

FSP(fractional seconds precision)

CREATE TABLE time_table(time_v TIME(3), datetime_v DATETIME(6), timestamp_v TIMESTAMP(4));

对应TIME类型,java中可以使用java.sql.Time,很遗憾它只支持到毫秒,不能到微妙,如果需要到微妙需要自己实现,或者使用java.time.LocalTime,它支持到纳秒。

对于DATETIME、TIMESTAMP类型java中可以使用java.sql.Date,但是只能支持到毫秒,可以使用java.time.LocalDateTime或java.sql.Timestamp类型,可以支持到纳秒。

@Test
void listDatetime0ByTimestamp() {
    Timestamp timestamp = new Timestamp(System.currentTimeMillis());
    timestamp.setNanos(517024000);
    List<DatetimeTimestampTO> tos = datetimeTimestampMapper.listDatetime6ByTimestamp(timestamp);
    tos.forEach(System.out::println);
}

微妙

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/247123.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++/语法@初始化列表

目录 初始化列表特征疑惑区别必在初始化列表中初始化的三种成员变量1、引用成员变量程序例子&#xff1a;运行结果&#xff1a; 2、const成员变量程序例子&#xff1a;运行结果&#xff1a; 3、自定义类型成员&#xff08;没有默认构造函数的类&#xff09;程序例子&#xff1a…

【LeetCode:2132. 用邮票贴满网格图 | 二维前缀和 + 二维差分和】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【docker 】Dockerfile指令学习

学习文档地址 上篇文章&#xff1a;【docker 】基于Dockerfile创建镜像 Dockerfile指令文档地址 .dockerignore 文件 Dockerfile指令 常见的指令 Dockerfile 指令说明FROM指定基础镜像&#xff0c;用于后续的指令构建。MAINTAINER指定Dockerfile的作者/维护者。&#xff…

伦敦金投资者的本质其实是风险管理者

长期在市场中可以稳定盈利的投资者&#xff0c;他们的秘密是什么&#xff1f;很多人以为&#xff0c;肯定是他有别人所没有的交易策略。其实并不是&#xff0c;交易技术固然很重要&#xff0c;但在持续盈利的问题上&#xff0c;技术所占的重要性是次要的&#xff0c;而主要的是…

Django 模型操作 - 多对多(九)

一、多对多关联管理器(对象调用) 前提&#xff1a;多对多&#xff08;双向均有关联管理器&#xff09;一对多&#xff08;只有多的那个类的对象有关联管理器&#xff0c;即反向才有&#xff09; 语法格式&#xff1a;正向&#xff1a;属性名反向&#xff1a;小写类名加 _set注意…

H3C ER G2系列路由器信息泄露漏洞

H3C ER G2系列路由器信息泄露漏洞 免责声明漏洞描述漏洞影响漏洞危害漏洞页面漏洞复现1. 构造poc2. 发生数据包&#xff0c;获取密码3. 登录系统 免责声明 仅用于技术交流,目的是向相关安全人员展示漏洞利用方式,以便更好地提高网络安全意识和技术水平。 任何人不得利用该文章…

详解—【C++】lambda表达式

目录 前言 一、lambda表达式 二、lambda表达式语法 2.1. lambda表达式各部分说明 2.2. 捕获列表说明 三、函数对象与lambda表达式 前言 在C98中&#xff0c;如果想要对一个数据集合中的元素进行排序&#xff0c;可以使用std::sort方法。 #include <algorithm> #i…

Java EE 多线程之多线程案例

文章目录 1. 多线程案例1.1 单例模式1.1.1 饿汉模式1.1.2 懒汉模式1.1.3 多线程下的单例模式 1.2 阻塞队列1.2.1 阻塞队列定义1.2.2 生产者消费者模型的意义1.2.4 标准库中的阻塞队列1.2.5 实现阻塞队列1.2.6 用阻塞队列实现生产者消费者模型 1.3 实现定时器1.3.1 标准库中的定…

V2X在做什么?连接未来智能出行的车联网(上)

来源&#xff1a;德思特测试测量 德思特分享丨V2X在做什么&#xff1f;连接未来智能出行的车联网&#xff08;上&#xff09; 原文链接&#xff1a;德思特分享 | V2X在做什么&#xff1f;连接未来智能出行的车联网&#xff08;上&#xff09; 欢迎关注虹科&#xff0c;为您提…

美易官方:零售销售数据提振信心

美易全球投资中心副总裁Kenny Jolin表示全球股市在经历了动荡之后逐渐恢复了稳定。最近&#xff0c;美国股市表现强劲&#xff0c;连续六天上涨&#xff0c;道琼斯指数也创下了新高。这一趋势不仅反映了投资者信心的恢复&#xff0c;也表明了全球经济正在逐渐复苏。 他说&#…

如何在Centos 7环境下安装MySQL并登录

目录 先获取MySQL官方yum源 然后正常使用yum命令下载mysql即可完成MySQL的下载 使用mysql客户端登录mysqld服务端 能够登录mysql客户端后&#xff0c;我们最后还需要做一点配置 先获取MySQL官方yum源&#xff08;包括对yum源的介绍&#xff09; 介绍一下yum源 yum源就是一…

文献管理器Zotero使用WebDAV结合内网穿透实现公网环境跨平台同步文献笔记

文章目录 一、Zotero安装教程二、群晖NAS WebDAV设置三、Zotero设置四、使用公网地址同步Zotero文献库五、使用永久固定公网地址同步Zotero文献库 Zotero 是一款全能型 文献管理器,可以 存储、管理和引用文献&#xff0c;不但免费&#xff0c;功能还很强大实用。 ​ Zotero 支…

net实践记录

文章目录 前言是否使用继承快捷输入 实体&#xff1b;引用class&#xff0c;提示有保护性System.NullReferenceException:“未将对象引用设置到对象的实例。” 总结 前言 记录使用.net 项目开发过程基础问题记录&#xff0c;便于快速回顾与查询&#xff1b; 是否使用继承 快捷…

关于git clone速度极慢的解决方法

&#xff01;&#xff01;&#xff01;&#xff01;前提条件&#xff1a;得有一个可靠且稳定的梯子&#xff0c;如果没有接下来的就不用看了 前言&#xff1a;我在写这篇文章前&#xff0c;也搜索过很多相关git clone速度很慢的解决方法&#xff0c;但是很多很麻烦&#xff0c…

Maven环境搭建及配置

Maven环境搭建及配置 1.下载部署 官方网站下载正式版的Maven文件,打开bin目录&#xff0c;复制路径然后去环境变量中的path下配置环境变量&#xff0c; 如果只有一个用户只需要在上面path配置复制的路径,当然也可以直接在下面配置,下面配置默认给所有用户都配置 设置完成打开控…

垃圾收集器及内存分配

目录 垃圾收集器种类 HotSpot虚拟机所包含的收集器 垃圾收集器部分源码 垃圾收集器后台日志参数说明与配对关系 1、串行垃圾收集器 串行垃圾收集器运行示意图 1&#xff09;、编写测试代码 2&#xff09;、设置垃圾回收为串行收集器 3&#xff09;、启动程序&#xff…

激活Windows过程及报错解决: 0x803f7001 在运行Microsoft Windows 非核心版本的计算机上, 运行“ slui.exe 0x2a 0x803f7001 “以显示错误文本

激活Windows过程及报错问题解决: 0x803f7001 在运行Microsoft Windows 非核心版本的计算机上&#xff0c;运行“ slui.exe 0x2a 0x803f7001 “以显示错误文本。 前言 最近在激活Windows过程中&#xff0c;遇到了报错: 0x803f7001 在运行Microsoft Windows 非核心版本的计算机上…

超详细 | 哈里斯鹰优化算法原理、实现及其改进与利用(Matlab/Python)

测试函数为F9 在MATLAB中执行程序结果如下&#xff1a; 在Python中执行程序结果如下&#xff1a; 哈里斯鹰优化算法(Harris Hawks Optimization , HHO)是 Heidari等[1]于2019年提出的一种新型元启发式算法&#xff0c;设计灵感来源于哈里斯鹰在捕食猎物过程中的合作行为以及突…

基础算法(3):排序(3)插入排序

1.插入排序实现 插入排序的工作原理是&#xff1a;通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已经排序的序列从后向前扫描&#xff0c;找到位置并插入&#xff0c;类似于平时打扑克牌时&#xff0c;将牌从大到小排列&#xff0c;每次摸到一张牌就插入到正确的位…

香港威雅报告:香港威雅学校入选英国《优秀学校指南》

今天&#xff0c;我们很荣幸地和大家分享一个特别的消息——香港威雅已接受了英国领先的学校审查机构——《优秀学校指南》&#xff08;The Good Schools Guide&#xff09;的全面评审。这是一家值得信赖的权威评审机构&#xff0c;相关工作人员来访并审查了我们的学校&#xf…