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