java - 如何使用 JdbcTemplate 正确处理此日期字段映射到 Spring Boot 项目中?

标签 java spring-boot jdbctemplate rowmapper

我已经很长时间没有使用 Spring 了,而且我发现这个 JdbcTemplate 行映射器映射日期字段有一些困难。

我尝试详细解释我的情况。

在我的数据库 (MariaDB) 上,我有一个名为 TREND002 的表:

+-----------------+----------+------+-----+---------+-------+
| Field           | Type     | Null | Key | Default | Extra |
+-----------------+----------+------+-----+---------+-------+
| Time_Stamp      | datetime | NO   | PRI | NULL    |       |
| Time_Stamp_ms   | int(11)  | NO   | PRI | NULL    |       |
| Sensor001DV     | double   | YES  |     | NULL    |       |
| Sensor002DV     | double   | YES  |     | NULL    |       |
| Sensor003DV     | double   | YES  |     | NULL    |       |
..............................................................
..............................................................
..............................................................
| Sensor00NDV     | double   | YES  |     | NULL    |       |

注 1:Time_Stamp 字段包含的值为 2010-10-22 16:50:12

然后我有这个 DTO 类映射上一个表的字段:

public class TrendDTO {

    private Date dateTime;
    private int timeStampMs;
    private String sensorValue;

    public TrendDTO() {
        super();
    }

    public TrendDTO(Date dateTime, int timeStampMs, String sensorValue) {
        super();
        this.dateTime = dateTime;
        this.timeStampMs = timeStampMs;
        this.sensorValue = sensorValue;
    }

    public Date getDateTime() {
        return dateTime;
    }

    public void setDateTime(Date dateTime) {
        this.dateTime = dateTime;
    }

    public int getTimeStampMs() {
        return timeStampMs;
    }

    public void setTimeStampMs(int timeStampMs) {
        this.timeStampMs = timeStampMs;
    }

    public String getSensorValue() {
        return sensorValue;
    }

    public void setSensorValue(String sensorValue) {
        this.sensorValue = sensorValue;
    }

    @Override
    public String toString() {
        return "TrendDTO [dateTime=" + dateTime + ", timeStampMs=" + timeStampMs + ", sensorValue=" + sensorValue + "]";
    }

}

基本上在这个 DTO 类中我有:

  • 映射表的日期时间字段的日期字段。
  • 映射表中 Time_Stamp_ms 字段的 int 字段。
  • 映射表中特定SensorXXXDV字段值的字符串字段(我知道从关系数据库的角度来看,这很难看......但我继承了这个项目,目前我无法更改)。

最后我有一个repository类,其中有这个方法:

@Override
public List<TrendDTO> findTrendListBySensorName(String tableName, String columnName) {

    List<TrendDTO> result = null;

    String RETRIEVE_TREND_BY_SENSOR_NAME = "SELECT Time_Stamp, Time_Stamp_ms, Sensor240DV FROM Delphys.TREND003";

    //result = jdbcTemplate.query(RETRIEVE_TREND_BY_SENSOR_NAME, BeanPropertyRowMapper.newInstance(TrendDTO.class));

    result =  jdbcTemplate.query(
            RETRIEVE_TREND_BY_SENSOR_NAME,
            (rs, rowNum) ->

                    new TrendDTO(
                            new java.util.Date(rs.getTimestamp("Time_Stamp").getTime()),
                            rs.getInt("Time_Stamp_ms"),
                            String.valueOf(rs.getDouble(columnName))
                    )
    );

    return result;
}

它工作正常,但通过这种方式,我获得了包含 dateTime 字段值的 TrendDTO 实例列表,如下所示:

dateTime=2010 年 10 月 22 日星期五 16:50:12 PDT 2010

日期完全正确,但我认为这是错误的格式。我必须以 JSON 格式将此 DTO 对象返回到前端,并且我需要以下格式的日期:

2010-10-22 16:50:12

我还尝试使用以下方法更改我的映射器代码:

result =  jdbcTemplate.query(
                RETRIEVE_TREND_BY_SENSOR_NAME,
                (rs, rowNum) ->

                        new TrendDTO(
                                //new java.util.Date(rs.getTimestamp("Time_Stamp").getTime()),
                                rs.getTimestamp("Time_Stamp"),
                                rs.getInt("Time_Stamp_ms"),
                                String.valueOf(rs.getDouble(columnName))
                        )
        );

如您所见,我只是使用 rs.getTimestamp("Time_Stamp") 但通过这种方式我获得了 dateTime 初始化,如下所示: 2010-10-22 16:50:12.0

正如你所看到的,它以 .0 结尾,它应该代表我不想要的毫秒。我可以指定格式以避免也放置此结束毫秒部分吗?

解决我的问题的另一种可能方法(也许是最好的解决方案)是:在这个非常可怕的数据库表中,毫秒信息包含在 Time_Stamp_ms 列中,目前该列与我的timeStampMs DTO 字段。

我可以修改以前的代码以将此信息直接封装到 DTO 对象的 dateTime 字段中吗?

我绝对不确定使用这种语法(它是 lambda 表达式吗?)这是可能的。我可以使用此语法来完成此操作,还是可以实现行映射器类来实现此行为?

最佳答案

我会这样做:

  1. 不要再使用旧的“Date”API,而使用较新的 (Java8+)LocalDateTime。假设您有一个相对较新的 JDBC 驱动程序,您可以这样做来获取 LocalDateTime,它可以为您节省一些尝试将时间戳转换为日期的操作。

    LocalDateTime yourLocalDateTime = rs.getObject("Time_Stamp", LocalDateTime.class) ;

  2. 您可以按照您想要的方式设置 LocalDateTime 的格式。要手动执行此操作,您可以使用DateTimeFormatter

    DateTimeFormatter 格式化程序 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formatDateTime = yourLocalDateTime.format(formatter);

  3. 如果您在 Spring Boot 项目中并序列化为 JSON,那么您所需要做的就是使用 @JsonFormat 注释来注释您的 DTO:

    @JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd HH:mm:ss") 私有(private) LocalDateTime myLocalDateTime;

关于java - 如何使用 JdbcTemplate 正确处理此日期字段映射到 Spring Boot 项目中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60562325/

相关文章:

java - 为什么要定义多个导入?

java - Spring Boot init.d not 未运行(未找到进程)

java - Spring @Transactional + jdbcTemplate 调用Web服务

java - Spring 4.0.0 中的 Spring JDBC 模板 java.lang.ClassCastException

java - 使用 jdbcTemplate,我可以执行什么简单查询来测试连接?

java - micro-payara 实例如何仅绑定(bind)到 localhost?

java - 请求中的空用户代理会在旧版 API 中创建 NPE

java - 无法启动部署在 websphere 8.5.5 上的 springboot 应用程序

java - Spring 启动项目: application run failed but gradle bootRun is ok in idea IDE

java - 从 xml 转换时是否可以保持 JSON 的排序,反之亦然