groovy 匹配java.sql.时间戳和DB2时间戳

nukf8bse  于 2022-11-01  发布在  Java
关注(0)|答案(1)|浏览(219)

我需要在URL中传递Timestamp值作为参数来检索一些数据。DB2中Timestamp的格式为:2022-05-25-11:10:44.662000,但在java.sql中的时间戳是:2022-05-25 11:10:44.0,当我传递它时,它返回空列表。
我的ActionController类方法:

@GetMapping(value = "/fetchData/{id}/{timestamp}")
  def fetchData(@PathVariable int id, @PathVariable Timestamp timestamp) {
    def serviceResult = actionService.fetchData(id, timestamp);
    return parseServiceResult(serviceResult)
  }

我的ActionService类方法:

ServiceResult fetchData(int id, Timestamp timestamp) {
    ServiceResult ret = new ServiceResult()
    List<DataDTO> retSet = new ArrayList<DataDTO>()
    List<String> errorMessage = new ArrayList<String>()
    try {
      retSet = actionEntity.fetchData(id, timestamp)
    } catch (CollectionsException e) {
      errorMessage << "ActionService.fetchData error"
      log.debug("ActionService.fetchData error" + e.getMessage())
    }
    ret = new ServiceResult(success: errorMessage.isEmpty(), result: retSet, errorMessageTextList: errorMessage)

    ret
  }

我的ActionEntity类方法:

ArrayList<DataDTO> fetchPoulsFromStorno(int id, Timestamp timestamp) throws CollectionsException {

    def sql = """SELECT * FROM NSNP.TABLE1 PT INNER JOIN NSNP.TABLE2 ST
                        ON (ST.COLUMN1 = PT.COLUMN1 AND
                        ST.COLUMN2 = PT.COLUMN2 AND
                        ST.COLUMN3 = PT.COLUMN3 AND
                        ST.COLUMN4 = PT.COLUMN4 AND
                        ST.COLUMN5 = PT.COLUMN5 AND
                        ST.COLUMN6 = PT.COLUMN6 AND
                        ST.COLUMN7 = PT.COLUMN7 AND
                        ST.COLUMN8 = PT.COLUMN8 )
                        WHERE ST.ID = $id AND ST.TIMESTAMP= $timestamp"""

    ArrayList<DataDTO> dataList = new ArrayList<DataDTO>()

    try {
      if (this.sql != null) {
        this.sql.eachRow(sql) {
          resultSet ->
            System.out.println(resultSet)
            DataDTO dataDTO = new DataDTO()
            dataDTO .setProperty1(resultSet.COLUMN1)
            dataDTO .setPropety2(resultSet.COLUMN2)
            dataDTO .setProperty3(resultSet.COLUMN3)

            dataList.add(dataDTO)
        }
      }
    } catch (SQLException se) {
      log.info "ActionEntity.fetchData error $se.message  executed sql: $sql"
    } finally {
      if (this.sql != null) {
        this.sql.close()
      }
    }
    dataList
  }

我不能提供给你准确真实的的数据,但我相信你会理解代码和我想做的事情。

avwztpqn

avwztpqn1#

tl;dr

您正在使用错误的类型。

  • 若要与类型为TIMESTAMP WITHOUT TIME ZONE的DB2数据行交换数据,请使用java.time.LocalDateTime
  • 若要与类型为TIMESTAMP WITH TIME ZONE的DB2数据行交换数据,请使用java.time.OffsetDateTime

永远不要使用有缺陷的旧类java.sql.Timestamp
👉 您的小时差异很可能是由于那个类调整了时区而造成的,这是有问题的,因为DB2中的TIMESTAMP列(TIMESTAMP WITHOUT TIME ZONE列)没有时区或偏移量。

详细信息

DB2中的时间戳格式为:2022年5月25日11时10分44.66万人
不,DB2中的TIMESTAMP类型没有格式。该类型不包含文本。该类型使用自己内部定义的数据来跟踪日期-时间值。
在Java中,TIMESTAMP WITHOUT TIME ZONE类型的DB2列的匹配类型为java.time.LocalDateTime
但是在java.sql.Timestamp中
永远不要使用Timestamp类。这个类是遗留的日期-时间类的一部分,在设计上存在着悲剧性的缺陷。它们在几年前被JSR 310中定义的现代 java.time 类所取代。Timestamp类被明确地替换为java.time.Instant,尽管为了与数据库交互,您可以使用OffsetDateTime类。
JDBC 4.2和更高版本要求所有JDBC驱动程序支持 java.time 类的相应子集。

时刻与非时刻

另一个问题是DB2中的TIMESTAMPTIMESTAMP WITHOUT TIME ZONE的缩写)故意缺少UTC偏移量或时区的上下文,没有偏移量或时区,该类型不能用于表示时刻,即时间线上的特定点。
相比之下,java.sql.Timestamp类 * 确实 * 表示一个时刻,即时间线上的一个特定点。
因此,DB2中的TIMESTAMPjava.sql.Timestamp不匹配。
👉 相反,要与DB2中的TIMESTAMP列交换值,请使用java.time.LocalDateTime类。与DB2类型一样,该类故意缺少偏移量或区域的上下文。

LocalDateTime ldt = LocalDateTime.parse( "2022-05-25T11:10:44.662000" ) ;

见此code run live at Ideone.com
如果您想使用一个字符串,请点击这里。
写作。

myPreparedStatement.setObject( … , ldt ) ;

检索。

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;

解决方案

DB2中的TIMESTAMP类型解析为非常精细的皮秒分辨率。
小数秒部分的位数使用0 - 12范围内的属性指定,默认值为6
nanosecond,十亿分之一秒,是九位数的小数秒,12位数代表picosecond,万亿分之一秒。

  • java.time* 类的精度为纳秒。

相关问题