You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从MySQL 5.7升级至8.0后Java连接器的datetime(3)小数秒问题

问题:MySQL 8.0 Aurora与Java连接器datetime(3)小数秒丢失问题

环境背景

  • 原AWS RDS MySQL 5.7升级至8.0.mysql_aurora.3.08.0
  • Java服务基于openjdk:8-jdk-alpine Docker镜像运行
  • MySQL连接器从mysql:mysql-connector-java:5.1.42升级为com.mysql:mysql-connector-j:8.4.0(同时测试过mysql:mysql-connector-java:8.0.33,问题一致)

问题现象

表中定义为datetime(3)的字段,当存储的时间小数秒为.000时:

  • Java代码读取到的时间字符串丢失小数部分(如2024-05-20 12:00:00而非预期的2024-05-20 12:00:00.000)
  • 导致Joda DateTime使用格式"YYYY-MM-dd HH:mm:ss.SSS"解析时失败
  • DBeaver(依赖Java连接器)显示无小数部分,MySQLWorkbench(依赖Connector/C++)显示正常

优雅解决方案

方案1:调整JDBC连接参数(强制保留小数部分)

在JDBC URL中添加useFractionalSeconds=true参数,强制Java连接器返回完整的时间字符串(包含.000小数部分),示例URL:

jdbc:mysql://your-rds-endpoint:3306/your-db?useFractionalSeconds=true&serverTimezone=UTC

该参数会让连接器严格按照字段定义的精度返回时间字符串,无论小数部分是否为0。

方案2:直接读取Timestamp类型(避免字符串解析)

放弃将datetime字段作为字符串读取,改为直接获取java.sql.Timestamp对象,再转换为Joda DateTime,彻底绕过字符串格式问题:

// 从ResultSet读取Timestamp
Timestamp timestamp = resultSet.getTimestamp("your_datetime_column");
// 转换为Joda DateTime
DateTime dateTime = new DateTime(timestamp.getTime(), DateTimeZone.UTC);

// 写入时直接使用Timestamp
preparedStatement.setTimestamp(1, new Timestamp(dateTime.getMillis()));

这种方式不需要依赖字符串格式,是更推荐的数据库时间读写方式,避免格式匹配的潜在问题。

方案3:调整Joda DateTime解析器兼容两种格式

如果无法修改数据库读取方式,可以修改DateTimeFormatter,让它同时兼容带小数和不带小数的时间字符串:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .appendPattern("YYYY-MM-dd HH:mm:ss")
    .appendOptional(DateTimeFormat.forPattern(".SSS").getParser())
    .toFormatter()
    .withZoneUTC();

这个解析器会自动识别时间字符串是否包含小数部分,无需额外的代码判断。

内容的提问来源于stack exchange,提问作者Perimosh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:55:03