在Spring JDBC Template中插入/更新含Timestamp的行时如何指定时区?
在JDBC及Spring JDBC Template中设置UTC时区的方案
刚好我之前也处理过类似的问题,给你详细梳理下JDBC和Spring JDBC Template里设置UTC时区的方案,尤其是你困惑的Spring JDBC插入/更新环节的时区指定问题:
一、原生JDBC的实现方式
你已经提到了原生JDBC的处理方法,这里再整理下方便参考:
插入/更新时指定UTC时区
直接通过PreparedStatement.setTimestamp()的重载方法,传入UTC时区的Calendar实例:
PreparedStatement myPreparedStatement = ... Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); myPreparedStatement.setTimestamp(1, myDateTime, utcCalendar);
查询时指定UTC时区
从ResultSet获取Timestamp时同样传入UTC的Calendar,确保读取到的是UTC时间:
ResultSet rs = ... rs.next(); Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); Timestamp utcTimestamp = rs.getTimestamp(1, utcCalendar);
二、Spring JDBC Template的时区处理
你说的没错,Spring JDBC Template查询时可以直接操作ResultSet,所以时区处理和原生JDBC一致,没什么问题。而插入/更新时因为Template封装了PreparedStatement的创建,我们可以通过以下两种方式来指定UTC时区:
方法1:使用PreparedStatementSetter(灵活快捷)
在update方法中传入自定义的PreparedStatementSetter,手动设置带UTC时区的Timestamp,适合单次使用的场景:
String insertSql = "INSERT INTO your_table (create_time) VALUES (?)"; jdbcTemplate.update(insertSql, new PreparedStatementSetter() { @Override public void setValues(PreparedStatement ps) throws SQLException { Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); ps.setTimestamp(1, new Timestamp(System.currentTimeMillis()), utcCalendar); } });
如果用Java 8+的Lambda表达式,代码会更简洁:
jdbcTemplate.update(insertSql, ps -> { Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); ps.setTimestamp(1, yourTimestamp, utcCalendar); });
方法2:自定义SqlTypeValue(复用性强)
如果你的项目中有很多地方需要设置UTC时区的Timestamp,可以自定义一个SqlTypeValue实现类,把时区处理逻辑封装起来,方便复用:
public class UtcTimestampSqlTypeValue extends AbstractSqlTypeValue { private final Timestamp timestamp; public UtcTimestampSqlTypeValue(Timestamp timestamp) { this.timestamp = timestamp; } @Override protected void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName) throws SQLException { Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); ps.setTimestamp(paramIndex, timestamp, utcCalendar); } }
使用的时候只需要把这个自定义类作为参数传入即可:
String updateSql = "UPDATE your_table SET update_time = ? WHERE id = ?"; jdbcTemplate.update(updateSql, new Object[]{ new UtcTimestampSqlTypeValue(yourUpdateTimestamp), targetId });
这样就能在Spring JDBC Template的插入/更新操作中,确保时间是以UTC时区写入数据库的啦。
内容的提问来源于stack exchange,提问作者supertonsky
相关产品推荐
相关产品推荐

