Java Mybatis 转换 LocalDateTime

Java LocalDateTime conversioning with mybatis

环境

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 的 TIMEDATETIMETIMESTAMP 只有微秒(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.