Java Mybatis 转换 LocalDateTime
Java LocalDateTime conversioning with mybatis
环境
- mybatis-spring-boot-starter 2.0.1
- mybatis 3.5.1
- mybatis-spring2.0.1
- mysql-连接器-java 8.0.16
jvm 时区:Asia/Seoul
我的测试查询
SELECT #{from}, #{to}
输入
YearMonth input = YearMonth.of(year, month)
LocalDateTime from = input.atDay(1).atStartOfDay()
LocalDateTime to = input.atEndOfMonth().atTime(LocalTime.MAX)
案例一。将 serverTimezone=UTC
添加到 jdbc url
案例一。将 serverTimezone=Asia/Seoul
添加到 jdbc url
[11:03:54] [main] [DEBUG] BaseJdbcLogger.debug(143)| ==> Preparing: SELECT ?, ?
[11:03:54] [main] [DEBUG] BaseJdbcLogger.debug(143)| ==> Parameters: 2020-01-01T00:00(LocalDateTime), 2020-01-31T23:59:59.999999999(LocalDateTime)
[11:03:54] [main] [DEBUG] Slf4jSpyLogDelegator.sqlTimingOccurred(368)| com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
1. SELECT 2020-01-01T00:00, 2020-01-31T23:59:59.999999999
{executed in 3 msec}
[11:03:54] [main] [INFO ] Slf4jSpyLogDelegator.resultSetCollected(610)|
|----------------------|----------------------|
|2019-12-31 15:00:00.0 |2020-01-31 15:00:00.0 |
|----------------------|----------------------|
|----------------------|----------------------|
[14:27:16] [main] [DEBUG] BaseJdbcLogger.debug(143)| ==> Preparing: SELECT ?, ?
[14:27:16] [main] [DEBUG] BaseJdbcLogger.debug(143)| ==> Parameters: 2020-01-01T00:00(LocalDateTime), 2020-01-31T23:59:59.999999999(LocalDateTime)
[14:27:16] [main] [DEBUG] Slf4jSpyLogDelegator.sqlTimingOccurred(368)| com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
1. SELECT 2020-01-01T00:00, 2020-01-31T23:59:59.999999999
{executed in 4 msec}
[14:27:16] [main] [INFO ] Slf4jSpyLogDelegator.resultSetCollected(610)|
|----------------------|----------------------|
|2020-01-01 00:00:00.0 |2020-02-01 00:00:00.0 |
|----------------------|----------------------|
|----------------------|----------------------|
Q1。 java LocalDateTime 是否用mybatis LocalDateTimeTypeHandler 转换成jdbc TIMESTAMP?
Q2。 mybatis LocalDateTimeTypeHandler 是否根据 jdbc servertimezone 设置转换值?
Q3。为什么我的 2020-01-31T23:59:59.999999999
值转换为 2020-02-01 00:00:00.0
?
- A1。不,自 3.5.1 版本以来,MyBatis 不会将
LocalDateTime
转换为 java.sql.Timestamp
(尽管在早期版本中会这样做)。
- A2。不,MyBatis 只是将值传递给驱动程序。您可以自己查看type handler implementation。
它实际上是执行转换的驱动程序,并且该行为在其跟踪器上被记录为错误。
https://bugs.mysql.com/bug.php?id=93444
- A3。 Java 的
LocalDateTime
具有纳秒(9 位)精度,而 MySQL 的 TIME
、DATETIME
和 TIMESTAMP
只有微秒(6数字)精度。 MySQL documentation 中解释了您观察到的行为。
Inserting a TIME, DATE, or TIMESTAMP value with a fractional seconds part into a column of the same type but having fewer fractional digits results in rounding.
环境
- mybatis-spring-boot-starter 2.0.1
- mybatis 3.5.1
- mybatis-spring2.0.1
- mysql-连接器-java 8.0.16
jvm 时区:Asia/Seoul
我的测试查询
SELECT #{from}, #{to}
输入
YearMonth input = YearMonth.of(year, month)
LocalDateTime from = input.atDay(1).atStartOfDay()
LocalDateTime to = input.atEndOfMonth().atTime(LocalTime.MAX)
案例一。将 serverTimezone=UTC
添加到 jdbc url
案例一。将 serverTimezone=Asia/Seoul
添加到 jdbc url
[11:03:54] [main] [DEBUG] BaseJdbcLogger.debug(143)| ==> Preparing: SELECT ?, ?
[11:03:54] [main] [DEBUG] BaseJdbcLogger.debug(143)| ==> Parameters: 2020-01-01T00:00(LocalDateTime), 2020-01-31T23:59:59.999999999(LocalDateTime)
[11:03:54] [main] [DEBUG] Slf4jSpyLogDelegator.sqlTimingOccurred(368)| com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
1. SELECT 2020-01-01T00:00, 2020-01-31T23:59:59.999999999
{executed in 3 msec}
[11:03:54] [main] [INFO ] Slf4jSpyLogDelegator.resultSetCollected(610)|
|----------------------|----------------------|
|2019-12-31 15:00:00.0 |2020-01-31 15:00:00.0 |
|----------------------|----------------------|
|----------------------|----------------------|
[14:27:16] [main] [DEBUG] BaseJdbcLogger.debug(143)| ==> Preparing: SELECT ?, ?
[14:27:16] [main] [DEBUG] BaseJdbcLogger.debug(143)| ==> Parameters: 2020-01-01T00:00(LocalDateTime), 2020-01-31T23:59:59.999999999(LocalDateTime)
[14:27:16] [main] [DEBUG] Slf4jSpyLogDelegator.sqlTimingOccurred(368)| com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
1. SELECT 2020-01-01T00:00, 2020-01-31T23:59:59.999999999
{executed in 4 msec}
[14:27:16] [main] [INFO ] Slf4jSpyLogDelegator.resultSetCollected(610)|
|----------------------|----------------------|
|2020-01-01 00:00:00.0 |2020-02-01 00:00:00.0 |
|----------------------|----------------------|
|----------------------|----------------------|
Q1。 java LocalDateTime 是否用mybatis LocalDateTimeTypeHandler 转换成jdbc TIMESTAMP?
Q2。 mybatis LocalDateTimeTypeHandler 是否根据 jdbc servertimezone 设置转换值?
Q3。为什么我的 2020-01-31T23:59:59.999999999
值转换为 2020-02-01 00:00:00.0
?
- A1。不,自 3.5.1 版本以来,MyBatis 不会将
LocalDateTime
转换为java.sql.Timestamp
(尽管在早期版本中会这样做)。 - A2。不,MyBatis 只是将值传递给驱动程序。您可以自己查看type handler implementation。
它实际上是执行转换的驱动程序,并且该行为在其跟踪器上被记录为错误。
https://bugs.mysql.com/bug.php?id=93444 - A3。 Java 的
LocalDateTime
具有纳秒(9 位)精度,而 MySQL 的TIME
、DATETIME
和TIMESTAMP
只有微秒(6数字)精度。 MySQL documentation 中解释了您观察到的行为。Inserting a TIME, DATE, or TIMESTAMP value with a fractional seconds part into a column of the same type but having fewer fractional digits results in rounding.