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