Spring JdbcTemplate查询MySQL datetime字段报LocalDateTime无法转java.util.Date错误
根因分析
- mysql-connector版本差异是核心触发原因:旧版驱动(5.1.x及更低版本)默认将MySQL的
DATETIME类型映射为java.sql.Timestamp(该类继承自java.util.Date),因此可以直接强转成功;8.0.x及更高版本的驱动默认支持JSR310规范的Java 8+时间API,会直接把DATETIME映射为java.time.LocalDateTime,该类和java.util.Date没有继承关系,强转就会抛出类转换异常。 - 若新项目使用的是Spring 5+、Spring Boot 2+版本,框架本身也对JSR310时间类型做了默认适配,也会影响JdbcTemplate的返回值类型。
修复方案
方案1:兼容旧代码逻辑,修改驱动配置
在JDBC连接参数中追加&useLegacyDatetimeCode=true(需同时配置正确的serverTimezone参数,比如serverTimezone=Asia/Shanghai),强制驱动使用旧的日期映射规则,返回java.sql.Timestamp类型,即可直接强转为java.util.Date。
方案2:改用Java 8+时间API(更推荐,避免SimpleDateFormat线程安全问题)
替换原有时间处理逻辑,直接适配LocalDateTime类型:
// DateTimeFormatter是线程安全的,可以直接定义为全局常量 private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 业务查询逻辑 String query = "select start_time as starttime from job_tbl"; List<Map<String, Object>> myList = jdbcTemplate.queryForList(query); for (Map<String, Object> map: myList) { LocalDateTime startTime = (LocalDateTime) map.get("starttime"); String dateTime = DATE_FORMATTER.format(startTime); }
如果确实需要转换为java.util.Date的场景,可通过如下方式转换:
LocalDateTime localDateTime = (LocalDateTime) map.get("starttime"); Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
内容的提问来源于stack exchange,提问作者Vinayak Nair
相关产品推荐
相关产品推荐

