1、近期发现一个问题,数据库表中字段edit_time最后更新时间,
在第一次插入,或者每更新一次update的时候,时间戳都比当前时间增加了8个小时;
2、date命令发现Linux服务器时间正确,为当前正确时间 2020-07-25 14:27:06:
3、通过mysql 客户端执行 select now(),数据库系统时间也是当前正确时间 2020-07-25 14:41:45,没有时差;
4、在数据库中,字段更新时间edit_time是通过mysql自动执行的,以下是建表字段语句:
`edit_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录修改时间';
mybatis拼接sql的mapper.xml文件并且有传入edit_time
所以这里当mybatis执行 插入/更新 方法,没有传入edit_time值的时候,才会通过 ON UPDATE CURRENT_TIMESTAMP 更新时间; 否则就按照程序传入的edit_time值拼接成sql执行,此时 ON UPDATE CURRENT_TIMESTAMP 失效:
(例如之前表中字段edit_time数据是2020-07-23 00:10:20,取出该条数据,执行完业务逻辑以后准备update,系统当前时间是2020-07-25 14:41:45,mybatis如果不传入edit_time字段值,就不会拼接sql,那么就按照2020-07-25 14:41:45更新,ON UPDATE CURRENT_TIMESTAMP 生效;
如果edit_time传入了值2020-07-25 22:41:45,那么就会按照传入的2020-07-25 22:41:45进行拼接sql更新,ON UPDATE CURRENT_TIMESTAMP 不会生效;)
5、jdbc代码中数据库连接时区配置,为东八区时间:
serverTimezone=GMT%2B8;
在网上找了一下解决方案,有说需要改成:serverTimezone=Asia/Shanghai,但是修改后经测试也并未生效;
6、给程序增加日志,发现从数据库取出来的时候转换为java实体对象(custLegal)的时候,就把时间字段edit_time增加了8个小时,而不是在执行mybatis插入/更新方法时增加的时间;转java对象采用的是 com.fasterxml.jackson.databind.ObjectMapper;
代码增加日志打印,查看custLegal的更新时间:
运行后查看Linux打印出来的日志:
表中存储的时间本来是2020-07-25 14:41:45,
第一次取出更新变成了2020-07-25 22:41:45,第二次取出更新又增加8小时,变成2020-07-26 06:41:45;
7、查看配置文件发现这样一行:
spring.jackson.time-zone=GMT+8 也是东八区时间,会不会由于跟jdbc的时区配置重复,导致时间再重新+8?
(经过测试,证明是这里的问题)
8、尝试几种解决:
(1)、把mybaits里面*****Mapper.xml中,所有插入/更新方法,对应的 editTime删掉;
这里没有传入edit_time,所以当然不会把java程序增加的8小时传入数据库,也是可以解决问题;
(2)、或者在转java对象时,jackson改fastjson;
原写法:
修改为 com.alibaba.fastjson.JSONObject
(3)、或者直接删除配置spring.jackson.time-zone=GMT+8 (推荐)