将 java.sql.Timestamp 与 DB2 时间戳匹配

Match java.sql.Timestamp with DB2 Timestamp

我需要将时间戳值作为参数传递到 URL 中以检索一些数据。 DB2中Timestamp的格式是:2022-05-25-11:10:44.662000,而在java.sql.Timestamp中是:2022-05-2511:10:44.0 当我通过它时,它 returns 空列表。

我的 ActionController class 方法:

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

我的 ActionService class 方法:

  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 class 方法:

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
  }

无法为您提供准确和真实的数据,但我相信您会理解代码和我正在尝试做的事情。

tl;博士

您使用了错误的类型。

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

永远不要使用有缺陷的遗产 class java.sql.Timestamp

您的时差可能是由于 class 调整时区造成的,这是有问题的,因为 DB2 中的 TIMESTAMP 列(TIMESTAMP WITHOUT TIME ZONE 列)没有时区或偏移量.

详情

Format of Timestamp in DB2 is: 2022-05-25-11:10:44.662000

不,DB2 中的 TIMESTAMP 类型没有格式。该类型不包含文本。该类型使用自己的 internally-defined 数据来跟踪 date-time 值。

Java 中 TIMESTAMP WITHOUT TIME ZONE 类型的 DB2 列的匹配类型是 java.time.LocalDateTime

but in java.sql.Timestamp

切勿使用 Timestamp class。 class 是遗留 date-time classes 的一部分,它们在设计中存在可悲的缺陷。多年前,它们被 JSR 310 中定义的现代 java.time classes 所取代。Timestamp class 专门被 java.time.Instant,尽管为了与数据库交互,您将使用 OffsetDateTime class.

JDBC 4.2 及更高版本要求所有 JDBC 驱动程序支持 java.time classes 的适当子集。

时刻与 not-a-moment

另一个问题是 DB2 中的 TIMESTAMPTIMESTAMP WITHOUT TIME ZONE 的缩写)故意缺少 offset-from-UTC 或时区的上下文。没有偏移量或区域,该类型不能用于表示时刻,时间轴上的特定点。

相比之下,java.sql.Timestamp class 确实代表了一个时刻,时间轴上的一个特定点。

所以 DB2 中的 TIMESTAMPjava.sql.Timestamp 不匹配。

相反,要与 DB2 中的 TIMESTAMP 列交换值,请使用 java.time.LocalDateTime class。与 DB2 类型一样,class 故意缺少偏移量或区域的上下文。

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

看到这个 code run live at Ideone.com

ldt.toString() is 2022-05-25T11:10:44.662

正在写作。

myPreparedStatement.setObject( … , ldt ) ;

检索。

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

分辨率

DB2 中的 TIMESTAMP 类型解析为非常精细的皮秒分辨率。引用手册:

The number of digits in the fractional seconds portion is specified using an attribute in the range 0 - 12 with a default of 6

nanosecond, a billionth of a second, is a fractional second of nine digits. Twelve digits represent a picosecond,万亿分之一秒。

java.time classes 的分辨率为纳秒。