美文网首页
mariaDb使用mysql驱动,导致dateTime格式精度丢

mariaDb使用mysql驱动,导致dateTime格式精度丢

作者: Neil_Wong | 来源:发表于2023-01-05 17:18 被阅读0次

    1、背景

    由于项目需要,需要将mysql数据库切换到maria数据库。

    2、问题

    将数据库切换到maria后,发现数据库dateTime格式丢失了毫秒精度。
    正常情况:


    image.png

    出现的问题:


    image.png
    发现丢失了毫秒精度。

    3、解决

    一开始以为是数据库格式的格式的问题,查看数据库格式后发现格式是datetime(3),保留3位毫秒数。是没有问题的。


    image.png

    后来直接操作数据库再次验证。


    企业微信截图_16729034036544.png
    发现是可以正确存储时间格式的。
    且同过日志查看到执行的sql参数也是正确的
    image.png

    那精度为什么丢失了呢?既然数据库没问题,数据也没有问题,此时怀疑问题出现在驱动上,在查看数据库驱动时发现使用的驱动是driver-class-name: com.mysql.jdbc.Driver;虽然mysql驱动和maria驱动区别不大,但还是存在差异。
    此时将数据库驱动更换为driver-class-name: org.mariadb.jdbc.Driver;再次执行操作,发现数据正常,毫秒精度得以保留。那说明问题的确出现在驱动上。

    4、原因

    虽然知道了驱动问题,但是根本原因是什么呢?
    查看mysql驱动包源码,了解到时间戳的处理是在com.mysql.cj.ClientPreparedQueryBindings这个类中:


    image.png image.png

    在方法setTimestamp中通过this.session.getServerSession().getCapabilities().serverSupportsFracSecs()会去做精度的控制。
    再看serverSupportsFracSecs()方法:是根据serverHasFracSecsSupport获取;


    image.png

    而serverHasFracSecsSupport是在com.mysql.cj.protocol.a.NativeCapabilities中:通过获取当前数据库serverVersion比较再来控制。当version版本低于5.6.4时,即会丢失精度。而这里获取到的版本号


    image.png
    通过debug得知我的获得的版本号是5.5.5,mysql驱动获取到的版本小于5.6.4,所以会忽略毫秒。
    image.png
    而在maria的驱动包中,我们通过源码发现在org.mariadb.jdbc.BasePreparedStatement类中处理了时间精度;
    image.png

    而这里的时间精度不会去和数据库版本号关联,也不会做丢失精度的处理。所以换了maria驱动包后,时间精度处理正常。

    至于为什么获得的版本号是5.5.5?

    实际上这是一个mariaDB的一个bug

    image.png
    参考:MariaDB 版本前缀“5.5.5-”未剥离 ·问题 #7972 ·PHP/PHP-SRC ·GitHub

    相关文章

      网友评论

          本文标题:mariaDb使用mysql驱动,导致dateTime格式精度丢

          本文链接:https://www.haomeiwen.com/subject/dvdjcdtx.html