今天在学习Spring Security 自动登录时遇到了MySQL数据库的时区问题,在网上找了很多资料都不能很好的解决问题,不过,最终问题被我解决,特此记录,希望能帮助到你(解决思路请直接看文章末尾)

  在实现自动登录功能的时候,Spring Security默认是依赖一张 persistent_logins 表的,此表的建表语句如下:

CREATE TABLE `persistent_logins` (
  `username` varchar(64) NOT NULL,
  `series` varchar(64) NOT NULL,
  `token` varchar(64) NOT NULL,
  `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

  其中 last_used 字段是 timestamp 格式的,当我进行自动登录的时候发现存入数据库的值是这样的

 

 

   我的mysql服务器系统时间是这样的

 

 

 系统时间是正确的,但是却相差8小时,直接在服务器登录mysql进行查询,结果是这样的

 

 

 查看时区设置

随后检查jdbc连接配置,当时配置是这样的(请记住红色框框的配置,这里才是问题重点)

 

 

 看上去配置的连接也没有问题,然后我就在本地写了个单元测试来查询persistent_logins表的数据,看看程序读出来的时间有没有问题

 

 

 通过 SimpleDateFormat打印的时间是没有问题的,但是mybatis的SQL日志里时间是有问题的

 

  通过这一些列的查询可以发现:

  1. 系统默认时间没有问题
  2. MySQL的时间是有问题的,与服务器对不上
  3. 程序通过jdbc连接配置,强行纠正了时区,但并未改变数据库存储的时间值

  作为一个严谨的程序员,我们当然要从根源上解决问题,因此首先要改的就是MySQL的时区设置,为了一劳永逸,我直接修改MySQL的配置文件,在Linux系统中,MySQL配置文件的默认位置如下:

/etc/my.cnf

  在配置文件的[mysqld]模块添加如下配置,然后重启MySQL服务

default_time_zone='+8:00'

  删除persistent_logins表原来的数据,重新进行自动登录操作,查看数据如下:

 

 

 登录MySQL查看时间如下:

 

 

 再跑单元测试,查询的时间如下:

 

MySQL时区是没有问题的,但是存入和查询的数据却是不正确的,这时我就开始怀疑是不是连接配置的问题了,我先试着将jdbc的时区配置去掉,删除如下配置

&serverTimezone=GMT

 清空数据库,再来一次,重启应用程序,模拟自动登录,然后查看数据库数据如下:

 

 

 终于,数据库存入的时间值正确了,然后再跑单元测试看一下查询的数据结果

 

 

同样没有问题 ,在看MySQL服务

 

 

 同样没有问题,至此,时区问题算是彻底解决了,

 

 

最后总结:如果你在项目中出现了MySQL时区问题,首先看下MySQL的时区配置是否正确,如果时区没有问题,则需要查看jdbc连接配置是否配置了serverTimezone,有时候这个配置是多余,如果配置了需要删除