Spring4.3.8+java8+mybatis3.4.4 + mariadb 时区时间问题

闲来无事,看一看 java8 新的时间API和mybatis怎么结合使用,于是就谢了个小demo尝试,没想到发生了“由时区问题引起的血案”。

  1. 环境
  • 本人电脑 MacBook Pro (15-inch, 2016) ,java version "1.8.0_131"
  • 项目使用 Spring4.3.8+java8+mybatis3.4.4 搭建
  • 数据库 使用kvm虚机搭建MariaDB-10.1.14
  1. 代码
public class TestLocalDate {

    private Date birthday;
    private LocalDate localDate;
    private LocalTime localTime;
    private LocalDateTime localDateTime;
    // 省略set get
}
<resultMap id="BaseMap" type="com.github.mmall.pojo.TestLocalDate">

        <result property="birthday" column="birthday"/>
        <result property="localDate" column="local_date"/>
        <result property="localTime" column="local_time"/>
        <result property="localDateTime" column="local_date_time"/>
    </resultMap>
    <select id="getTestLocalDate" resultMap="BaseMap">
        SELECT * FROM test_localdate
    </select>

测试代码 输入图片说明

 @Test
    public void testLocalDateService() {

        TimeZone aDefault = TimeZone.getDefault();

        System.out.println(aDefault.getDisplayName());
        List<TestLocalDate> localDate = localDateService.getLocalDate();
        TestLocalDate testLocalDate = localDate.get(0);

        
        System.out.println(testLocalDate);

    }
  1. 结果 数据库数据

TestLocalDate{birthday=Thu Aug 10 02:32:50 CST 2017, localDate=2017-08-09, localTime=13:32:50, localDateTime=2017-08-09T13:32:50}

  1. 发生了什么 查询本机,数据库服务器,数据库的时区
# 本机
# gx @ gxdemacbook-pro in ~ [10:22:26]
$ date
2017年 8月 9日 星期三 10时22分28秒 CST

# gx @ gxdemacbook-pro in ~ [10:22:28]
$ date -R
Wed, 09 Aug 2017 10:35:31 +0800
# 数据库服务器  
[root@kvm-010834 ~]# date
Wed Aug  9 14:47:13 CST 2017
[root@kvm-010834 ~]# date -R
Wed, 09 Aug 2017 14:47:17 +0800
# 数据库
MariaDB [mmall]> show variables like "%time_zone%";
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)

MariaDB [mmall]> select now();
+---------------------+
| now()               |
+---------------------+
| 2017-08-09 14:48:54 |
+---------------------+
1 row in set (0.00 sec)

至此也没有发现什么不一样呀,为什么java 查出的时间会有差异呢?接下来直接上driver模式,去掉mybatis

@Test
    public void testJDBC() {

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection connection = DriverManager.getConnection("jdbc:mysql://9.111.111.193:3306/mmall", "root", "passw0rd");

            Statement statement = connection.createStatement();

            ResultSet resultSet = statement.executeQuery("select birthday from test_localdate");

            while (resultSet.next()) {
                Timestamp birthday = resultSet.getTimestamp("birthday");

                System.out.println("Timestamp : "+birthday);
                Date birthday1 =
                        resultSet.getDate("birthday");

                Time birthday2 = resultSet.getTime("birthday");

                System.out.println("Date : "+birthday1);
                System.out.println("Time : "+birthday2);

                String time =resultSet.getString("birthday");

              SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                System.out.println("String : " +time);
                System.out.println(sdf.parse(time));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }

    }

发现结果没有变化,只有resultSet.getString("birthday"); 作为 字符串返回时候才和数据库显示相同,使用时间函数返回的结果都不正确。 应该还是数据库的原因。查询my.cnf也没有配置zone相关的信息,自认为使用和服务器应该一样。但是

进入mysql command

MariaDB [mmall]>  set global time_zone = '+8:00';

然后在返回执行,奇迹出现了。结果正确。

  1. 记录
    安装服务器的时候一定要配置 my.cnf 添加 default-time_zone = '+8:00',设置时区;

select now();语句是服务器的时间;

CST可以为如下4个不同的时区的缩写: 美国中部时间:Central Standard Time (USA) UT-6:00 澳大利亚中部时间:Central Standard Time (Australia) UT+9:30 中国标准时间:China Standard Time UT+8:00 古巴标准时间:Cuba Standard Time UT-4:00 数据库show variables like "%time_zone%";语句并不能保证时区正确。

  1. mybatis+ java8

添加依赖,即可,

  <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-typehandlers-jsr310</artifactId>
      <version>1.0.2</version>
    </dependency>

看到其他bolg有写到 这种方式只对3.4以上mybatis生效。 若版本小于3.4,则需手动添加 typeHandler

<typeHandlers>  
    <typeHandler handler="org.apache.ibatis.type.InstantTypeHandler" />  
    <typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler" />  
    <typeHandler handler="org.apache.ibatis.type.LocalDateTypeHandler" />  
    <typeHandler handler="org.apache.ibatis.type.LocalTimeTypeHandler" />  
    <typeHandler handler="org.apache.ibatis.type.OffsetDateTimeTypeHandler" />  
    <typeHandler handler="org.apache.ibatis.type.OffsetTimeTypeHandler" />  
    <typeHandler handler="org.apache.ibatis.type.ZonedDateTimeTypeHandler" />  
</typeHandlers>  

转载于:https://my.oschina.net/heiseguoguo/blog/1505291

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值