mybatis中使用Java8 LocalDateTime时间转化的可能导致的问题

Java8中的LocalDateTime的表示的精度可以达到纳秒。

而Mysql中的datetime类型支持的精度只能达到毫秒级别。

这就导致了一个问题。

如果我想查询1天内的数据,可以通过以下SQL

@Select("select * from table where create_time >= #{startDate} and create_time <= #{endDate}")
List selectData(@Param("startDate")LocalDateTime startDate, @Param("endDate")LocalDateTime endDate);

例如我想查询2020-01-01当天的所有数据,调用代码如下:

LocalDateTime startDate = LocalDate.of(2020,1,1).atStartOfDay();
LocalDateTime endDate = LocalDate.of(2020,1,1).atTime(LocalTime.MAX);

fooMapper.selectData(startDate, endDate);

这个地方你会发现除了2020-01-01的数据,2020-01-02的数据也可能被查询出来。

实际上最终的执行的SQL如下:

select * from table where create_time >= '2020-01-01 00:00:00.0' and create_time <= '2020-01-01 23:59:59.999999999'

这个SQL最终执行的效果等效于:

select * from table where create_time >= '2020-01-01 00:00:00.0' and create_time <= '2020-01-02 00:00:00.0'

这里的原因就在于mysql中秒的精度只能达到毫秒,范围在0-999999之间,Java中的2020-01-01 23:59:59.999999999会被隐式转化为2020-01-02 00:00:00.0

因此就造成了结果的不准确。

这里的解决方法可以手动指定一天的结束时间,如下:

LocalDateTime endDate = LocalDate.of(2020,1,1).atTime(23,59,59);

参考资料

https://dev.mysql.com/doc/refman/5.7/en/fractional-seconds.html

https://blog.csdn.net/tlojy/article/details/113121113

上一篇:gdb 调试 segment default 问题


下一篇:JDBC