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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM