mysql8.0.11 datetime精度丢失的问题

测试接口时,代码中使用LocalDateTime.now()生成时间戳,并insert到db中类型为datetime的字段中,查看db后发现存入的时间与系统生成的时间不同,多了一秒,打断点发现new 出来的Date为2019-06-14 13:02:58.789,存入的数据为2019-06-14 13:02:59。经过排查解决后,记录一下此次问题。

排查思路

首先这很明显可以看出是因为时间的精度丢失问题,所以想到了两个排查思路:

  1. 客户端代码(即mysql-connector-jar)进行了四舍五入,导致丢失了精度。
  2. server端即数据库进行了四舍五入,导致丢失了精度。

client端

查看了驱动包中的代码,发现如果server端支持的话,是会拼上毫秒的精度的。

#com.mysql.cj.ClientPreparedQueryBindings

    public void setTimestamp(int parameterIndex, Timestamp x, TimeZone tz) {
        if (x == null) {
            setNull(parameterIndex);
        } else {
            if (!this.sendFractionalSeconds.getValue()) {
                x = TimeUtil.truncateFractionalSeconds(x);
            }

            if (this.tsdf == null) {
                //这里截断了精度
                this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US);
            }

            this.tsdf.setTimeZone(tz);

            StringBuffer buf = new StringBuffer();
            buf.append(this.tsdf.format(x));
            //如果server支持fractional seconds的话,就加上毫秒的精度
            if (this.session.getServerSession().getCapabilities().serverSupportsFracSecs()) {
                buf.append('.');
                buf.append(TimeUtil.formatNanos(x.getNanos(), true));
            }
            buf.append('\'');

            setValue(parameterIndex, buf.toString(), MysqlType.TIMESTAMP);
        }
    }

查资料发现时从5.1.21版本之后,才可以拼接上毫秒的精度。当前版本为8.0.11。

server端

执行如下sql

create table my_dev.test_date (

    table_id varchar(10) ,
    datetime0  datetime,
)ENGINE=INNODB DEFAULT CHARSET=utf8;


insert into my_dev.test_date values (1,'2019-02-22 13:02:58.789');

发现结果为:

在这里插入图片描述

然后就发现了问题的所在。

思考

经过查阅资料发现,如果创建表示字段类型为datetime或者timestamp时,默认精度是到秒的,也就是说如果想保存毫秒的精度,需要创建为如下:

create table my_dev.test_date (

    table_id varchar(10) ,
    datetime0  datetime,
    datetime1 datetime(1),
    datetime2 datetime(2),
    datetime3 datetime(3)
)ENGINE=INNODB DEFAULT CHARSET=utf8;


insert into my_dev.test_date values (1,'2019-02-22 13:02:58.789','2019-02-22 13:02:58.789','2019-02-22 13:02:58.789','2019-02-22 13:02:58.789');

执行结果为:

在这里插入图片描述

以上。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值