MyBatis直接使用LocalDateTime时间类型以及MySQL时区问题排错
时间类型
Java 8提供了新的时间API,相关介绍大家可以自行搜索或者直接参考这篇Java中的时间与时区,因此大家在写实体类时,可以放弃用以前的Date或者Timestamp类型了,直接用LocalDateTime类就行了,MyBatis从3.4.5版本开始就完全支持这种类型了,根本不用自己再去写什么类型转换,目前网上搜到的大部分文章还是让我们自己去实现,其实不用的。
我们来看看其官方文档( https://github.com/mybatis/mybatis-3/releases ):
mybatis-3.4.5
@harawata harawata released this on 20 Aug 2017 · 472 commits to master since this release
Enhancements:
Make default enum type handler customizable. #971
Make mapper method and its interface type accessible to SqlProvider. #1055
Allow using configuration properties in SqlProvider. #1061
Merge type handlers for JSR-310 (Java Date and Time API) into the core. #974
JSR-310相关规范在这个版本就已经支持了,所以大家只要不小于此版本的就放心用吧。举个例子:
1 | public class User { |
这样就OK了,如果你数据库表存的是datetime类型的话,MyBatis自动帮你解析转换,你不用做额外工作。
注意:
这里LocalDateTime默认是不包含时区信息的,会取当前机器时间的时区,其实一般情况下,是没有问题的,我用阿里云的服务器(在深圳),直接打印出来就是:
1 | System.out.println(LocalDateTime.now()); |
当然这样可能你不是很放心,那么就指明时区:
1 | System.out.println(LocalDateTime.now(ZoneId.of("+08:00"))); |
MySQL时区有问题(相差13或14小时)
这个问题最开始让我非常头疼,明明我的Tomcat和MySQL在同一个服务器上,Java代码打印时间出来都是对的,结果一插入数据库时间就错了。
然后进入数据库查看时间和时区:
1 | select curtime(); |
发现时间也没问题,都是北京时间,那为什么通过JDBC一插就差那么十几个小时呢?
问题的原因在这里:一次 JDBC 与 MySQL 因 “CST” 时区协商误解导致时间差了 14 或 13 小时的排错经历
解决办法:
手动修改MySQL的时区,明确指定:
1 | set global time_zone='+08:00'; |
或者修改my.cnf配置文件,一劳永逸,添加:
1 | [mysqld] |
即可,最后记得重启MySQL服务,最好还能重启一下Tomcat。