MySQL Spring JDBC API JdbcTemplate日期时间字段的测试使用
建测试表
CREATE TABLE `t_date` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`f_date` date NULL,
`f_datetime` datetime(0) NULL,
`f_timestamp` timestamp(0) NULL
)
实体类TData
TDate.java
package com.test.jdbcapi;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.sql.Date;
import java.sql.Timestamp;
import lombok.Data;
@Data
public class TDate {
private int id;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd",timezone = "GMT+8")
private Date f_date;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Timestamp f_datetime;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Timestamp f_timestamp;
}
添加测试数据
@Test
void testInsert() throws JsonProcessingException, ParseException {
System.out.println("testInsert");
java.util.Date d = new java.util.Date();
TDate tdate = new TDate();
tdate.setF_date(new Date(d.getTime()));
tdate.setF_datetime(new Timestamp(d.getTime()));
tdate.setF_timestamp(new Timestamp(d.getTime()));
String sql = "insert into t_date(f_date,f_datetime,f_timestamp) values(?,?,?)";
int i = jdbcTemplate.update(sql, tdate.getF_date(), tdate.getF_datetime(), tdate.getF_timestamp());
System.out.println("insert:" + i);
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(tdate);
System.out.println(str);
}
尝试使用JdbcTemplate.queryForObject来查询数据
@Test
void testQueryForObjectByDateTime() throws JsonProcessingException, ParseException {
System.out.println("testQueryForObjectByDateTime");
int id = 1;
String sql = "select * from t_date where id=?";
TDate tdate = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(TDate.class), id);
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(tdate);
System.out.println(str);
}
单元测试及问题处理
在测试过程发现如果MySQL数据库字段使用了datatime类型时,这个数据库驱动SqlRowSet对象会字段转换为java.time.LocalDateTime类型,这里使用针对日期时间字段的取值 rowSet.getDate()或rowSet.getTimestamp()都是会出错的,这只在自行使用SqlRowSet时会出现这个错误
@Test
void testDateQueryForRowSet() {
System.out.println("testDateQueryForRowSet");
String sql = "select * from t_date";
SqlRowSet rowSet = jdbcTemplate.queryForRowSet(sql);
while (rowSet.next()) {
Date f_date = rowSet.getDate("f_date");
Date f_datetime = rowSet.getDate("f_datetime");
Timestamp f_timestamp = rowSet.getTimestamp("f_timestamp");
System.out.println("日期:" + f_date);
System.out.println("日期时间:" + f_datetime);
System.out.println("timestamp:" + f_timestamp);
}
}
单元测试出现错误了
java.lang.ClassCastException: class java.time.LocalDateTime cannot be cast to class java.sql.Timestamp (java.time.LocalDateTime is in module java.base of loader 'bootstrap'; java.sql.Timestamp is in module java.sql of loader 'platform')
这里其实MySQL数据库表中类型为DataTime的字段f_datetime,通过JDBC SqlRowSet对象获取到的f_datetime字段类型为java.time.LocalDateTime 无法通过SqlRowSet.getTimestamp获取,对象类型不一致
在Timestamp f_datetime = rowSet.getTimestamp("f_datetime");这里设置断点,在前面增加一行Object obj=rowSet.getObject("f_datetime");使用Debug可以看到
debug运行到断点后,在Threads & Variables 这里可以看到变量情况
将Timestamp f_datetime = rowSet.getTimestamp("f_datetime");改为
Timestamp f_datetime =Timestamp.valueOf( (java.time.LocalDateTime) rowSet.getObject("f_datetime"));
可以取出数据,需要自行转换,如果在MySQL中字段使用类型为Date或Timestamp则没有那么麻烦去自行转换