如何让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




