serverTimeZone的作用,mysql的时区,时区问题(2)

注意:以下所有的内容,是通过实验得出,并进行总结,如有错误,请指正

前置知识

@DateTimeFormat 和 @JsonFormat 的详细研究,以及timezone="GMT+8"的研究,时区问题(1)
因为有了前置知识,所以这篇也很好理解,讨论一下内容

  1. mysql 数据库的时区问题
  2. serverTimeZone 到底什么作用。

实验开始

场景描述:

  • mysql 的时区在东4区,web服务器的时区在东8区,人在东8区,存日期到东4区的mysql服务器,并且再取出来。

实验1

  1. 修改mysql 的时区。
SET GLOBAL time_zone = '+4:00';
SET time_zone = '+4:00';
SHOW VARIABLES LIKE "%time_zone%";

serverTimeZone的作用,mysql的时区,时区问题(2)_第1张图片

  1. 配置
  • 数据库连接url(未指定serverTimeZone)

jdbc:p6spy:mysql://127.0.0.1:3306/mybatis_plus?characterEncoding=UTF-8&&useSSL=false&useUnicode=true

  1. web服务器controller代码,以及发送http请求的运行结果。
    @PostMapping("put")
    public String put(){
     
        User user = new User();
        Date date = new Date();
        System.out.println(date); // Sat Mar 07 21:36:04 CST 2020
        user.setDate(date);
        System.out.println(user); // User(id=null, date=Sat Mar 07 21:36:04 CST 2020)
        userMapper.insert(user); // INSERT INTO mybatis_plus.user ( id, date ) VALUES ( 1236284482563080193, '2020-03-07T21:36:04.321+0800' )
        System.out.println(userMapper.selectById(user.getId())); // User(id=1236284482563080193, date=Sat Mar 07 21:36:04 CST 2020)
        return "okPost";
    }

结果分析,目前看起来都挺好。

  1. mysql服务器
    serverTimeZone的作用,mysql的时区,时区问题(2)_第2张图片
  • 问题来了:
    我传的是21点,怎么存进去成了17点。
  • 结果分析:
    mysql的时区是东4区,web服务器的时区是东8区,Web服务器在执行SQL的时候,传入日期字符串是这样的 ‘2020-03-07T21:36:04.321+0800’ ,也就是这是一个东8区的日期字符串。(这点有些问题,问题是,插入的时候转成东4区时间的操作是发生在web服务器端,还是发生在mysql服务器端。(如果有高人,还请指点)但是这并不影响后续的测试,这里假设发生在web服务器端)
    web服务器端 分析你mysql在东4区,我比你快4个小时,也就是你是,21-4=17,存的时候也就是17点。

实验1.1,从数据库,取值

  1. web controller 代码,以及测试结果
@GetMapping("user")
public String get(@RequestParam Long id){
     
    String dateString = userMapper.getDateString(id); // select date from user where id = 1236284482563080193
    System.out.println(dateString); // 2020-03-07 17:36:04
    
    Date date = userMapper.getDate(id); // select date from user where id = 1236284482563080193 
    System.out.println(date); // Sat Mar 07 21:36:04 CST 2020
    
    User user = userMapper.selectById(id); // SELECT id,date FROM mybatis_plus.user WHERE id=1236284482563080193 
    System.out.println(user); // User(id=1236284482563080193, date=Sat Mar 07 21:36:04 CST 2020)
    return "okGet";
    }

结果分析:

  1. 数据库的时间是 2020-03-07 17:36:04,用String类型接收,结果就是数据库的日期。可知取出日期时的日期转换,不是发生在数据库,而是发生在web服务器,也就是jvm里。
  2. 转成Date的日期,比数据库的快了4小时,原因是数据库是东4区,而web服务器是东8区,东8比东4时间快4小时。

问题是:为什么web服务器知道mysql服务器是东4区?

  • 我认为是web服务器在与数据服务器连接的时候,就获取到数据库的时区,如果数据库的时区未设置,为空,那么web服务器根本无法连接,数据库服务器,会出现错误日志,让指定 serverTimeZone。
    问题又来了:serverTimeZone 的作用是什么呢?

探索 serverTimeZone 的作用

实验2,向mysql服务器添加数据

之前的配置web服务器在东8区,mysql时区是东4区,依旧不变,
现在修改web服务器端的url连接:(修改为GMT+8)

jdbc:p6spy:mysql://127.0.0.1:3306/mybatis_plus?characterEncoding=UTF-8&&useSSL=false&serverTimezone=GMT%2B8&useUnicode=true

  1. web服务器controller,以及执行结果
@PostMapping("put")
public String put(){
     
    User user = new User();
    Date date = new Date();
    System.out.println(date); // Sat Mar 07 21:57:31 CST 2020
    user.setDate(date);
    System.out.println(user); // User(id=null, date=Sat Mar 07 21:57:31 CST 2020)
    userMapper.insert(user); // INSERT INTO mybatis_plus.user ( id, date ) VALUES ( 1236289879764172801, '2020-03-07T21:57:31.123+0800' )
    System.out.println(userMapper.selectById(user.getId())); // User(id=1236289879764172801, date=Sat Mar 07 21:57:31 CST 2020)
    return "okPost";
}

结果分析:

  • 看起来没什么问题
  1. mysql服务器
    在这里插入图片描述
    结果分析:
  • 结果正确。

实验2.1 ,从服务器获取数据

  1. web服务器controller,以及执行结果
@GetMapping("user")
public String get(@RequestParam Long id){
     
    String dateString = userMapper.getDateString(id); // select date from user where id = 1236289879764172801
    System.out.println(dateString); // 2020-03-07 21:57:31

    Date date = userMapper.getDate(id); // select date from user where id = 1236289879764172801
    System.out.println(date); // Sat Mar 07 21:57:31 CST 2020

    User user = userMapper.selectById(id); // SELECT id,date FROM mybatis_plus.user WHERE id=1236289879764172801 
    System.out.println(user); // User(id=1236289879764172801, date=Sat Mar 07 21:57:31 CST 2020)
    return "okGet";
}

结果分析:

  • 结果正确

总结

serverTimeZone的作用就是指定web服务器和mysql服务器的会话期间的mysql服务器时区,就是临时指定mysql服务器的时区。

你可能感兴趣的:(Java,java)