You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让Spring JdbcTemplate将MySQL datetime映射为java.time.LocalDateTime?

解决JdbcTemplate将MySQL datetime映射为LocalDateTime的问题

我来帮你搞定这个问题——默认情况下JdbcTemplate会把MySQL的datetime和timestamp都转成java.sql.Timestamp,要实现datetime映射为java.time.LocalDateTime,有两种实用方案,看你的项目环境来选:

方案一:通过数据源配置自动映射(推荐Spring Boot项目)

这种方式不需要修改代码,只要配置MySQL驱动的参数,让它自动用新的日期时间API处理字段。

首先确保你用的是MySQL 8.x版本的驱动com.mysql.cj.jdbc.Driver),然后在配置文件里添加关键参数:

application.properties 配置

# 数据库连接URL,注意添加后面的日期时间相关参数
spring.datasource.url=jdbc:mysql://localhost:3306/your_db_name?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false&useJDBCCompliantTimezoneShift=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Hikari连接池的额外配置(如果用Hikari的话)
spring.datasource.hikari.data-source-properties.useLegacyDatetimeCode=false
spring.datasource.hikari.data-source-properties.serverTimezone=UTC

关键参数说明:

  • useLegacyDatetimeCode=false:禁用旧的日期时间处理逻辑,让驱动使用Java 8+的java.time类型
  • serverTimezone=UTC:指定时区,避免时区转换问题
  • useJDBCCompliantTimezoneShift=true:确保时区转换符合JDBC规范

配置完之后,直接用原来的queryForList方法查询,datetime字段就会自动映射为LocalDateTime了:

List<Map<String, Object>> generic = jdbcTemplate.queryForList("SELECT * FROM datetimetest");
// 验证类型:generic.get(0).get("thedatetime") 会是 LocalDateTime 类型

方案二:自定义RowMapper手动转换(适合传统Spring项目或精细控制)

如果你的项目不是Spring Boot,或者需要更灵活的字段转换逻辑,可以自定义RowMapper来手动处理类型转换:

自定义RowMapper实现

import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import org.springframework.jdbc.core.RowMapper;

public class DateTimeTestRowMapper implements RowMapper<Map<String, Object>> {
    @Override
    public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
        Map<String, Object> rowMap = new HashMap<>();
        rowMap.put("id", rs.getInt("id"));
        // 直接将datetime字段读取为LocalDateTime
        rowMap.put("thedatetime", rs.getObject("thedatetime", LocalDateTime.class));
        // timestamp字段可以选择转成LocalDateTime,或者保留Timestamp
        rowMap.put("thetimestamp", rs.getTimestamp("thetimestamp").toLocalDateTime());
        return rowMap;
    }
}

使用自定义RowMapper查询

List<Map<String, Object>> result = jdbcTemplate.query("SELECT * FROM datetimetest", new DateTimeTestRowMapper());

注意事项

  • 必须使用MySQL Connector/J 8.x版本,5.x版本的驱动对java.time类型支持有限,无法实现自动映射
  • 如果用Maven,记得引入正确的驱动依赖:
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version> <!-- 用最新稳定版即可 -->
</dependency>

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

火山引擎 最新活动