将 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 中的 TIMESTAMP
(TIMESTAMP WITHOUT TIME ZONE
的缩写)故意缺少 offset-from-UTC 或时区的上下文。没有偏移量或区域,该类型不能用于表示时刻,时间轴上的特定点。
相比之下,java.sql.Timestamp
class 确实代表了一个时刻,时间轴上的一个特定点。
所以 DB2 中的 TIMESTAMP
与 java.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 的分辨率为纳秒。
我需要将时间戳值作为参数传递到 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 中的 TIMESTAMP
(TIMESTAMP WITHOUT TIME ZONE
的缩写)故意缺少 offset-from-UTC 或时区的上下文。没有偏移量或区域,该类型不能用于表示时刻,时间轴上的特定点。
相比之下,java.sql.Timestamp
class 确实代表了一个时刻,时间轴上的一个特定点。
所以 DB2 中的 TIMESTAMP
与 java.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 的分辨率为纳秒。