一.问题背景:
项目中使用到MybatisPlus为持久层框架,保存数据时直接调用其方法。
今天在帮实习生调试一个bug的时候,遇到了这个问题。使用刚刚保存完返回的对象信息,进行数据库查询,并没有查询到数据记录信息。
TyPatrol tyPatrol = new TyPatrol();
tyPatrol.setState(state);
super.save(tyPatrol);
TyPatrol entity = super.selectEntity(tyPatrol);
根据ID查询到刚才保存的数据记录后, 发现了Java生成的日期和数据库保存的日期时间上不相同的问题。
TyPatrol tyPatrol = new TyPatrol();
tyPatrol.setState(state);
boolean save = save(tyPatrol);
System.out.println(tyPatrol.getRecordCreateDate().getTime());
//获取到值为:1606814241937
TyPatrol tyPatrol1 = selectByPrimaryKey(tyPatrol.getId());
System.out.println(tyPatrol1.getRecordCreateDate());
//获取到值为:1606814242000
二.原因:
Mysql中record_create_date字段的数据类型为datetime,该类型精度支持到秒,1552319999999[“2018-03-11 23:59:59”]这个数据和"2018-03-12 00:00:00"不是相差一秒 而是一毫秒。只是1552319999999[“2018-03-11 23:59:59”]展示的时候去掉了999毫秒,所以数据库存储1552319999999时四舍五入,存入"2018-03-12 00:00:00"。
1 秒=1000 毫秒。所以datetime类型在存储的时候会将时间戳的最后3位进行四舍五入。
三.解决方案:
如果有保存毫秒、微秒的需求,可以更改datetime类型的长度。在创建表的时候,如果datetime类型没有指定长度,其默认为0。可以将其长度更改为3,即可保存到毫秒级别的数据量。
mysql>
mysql> CREATE TABLE student( c1 TIME(2), c2 DATETIME(6), c3 TIMESTAMP(3) );
Query OK, 0 rows affected (0.03 sec)
mysql> INSERT INTO student VALUES ('17:51:04.777', '2017-07-16 12:00:12.234', '2017-07-16 12:00:12.234');
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+-------------+----------------------------+------------------------+
| c1 | c2 | c3 |
+-------------+----------------------------+------------------------+
| 17:51:04.78 | 2017-07-16 12:00:12.234000 | 2017-07-16 12:00:12.234 |
+-------------+----------------------------+------------------------+
将其长度更改为3时,可以精确到毫秒级别。将其长度更改为6时,即可以保存微秒级别的数据。