关于Mysql的时间类型以及带来的错误

  • 来源:开源中国

关于Mysql的时间类型范围

网上说:

关于mysql时间类型datetime与timestamp范围

datetime类型取值范围:1000-01-01 00:00:00 到 9999-12-31 23:59:59

timestamp类型取值范围:1970-01-01 00:00:00 到 2037-12-31 23:59:59

timestamp类型具有自动初始化和自动更新的特性。

我使用mysql5.7  

建表使用数据版本字段(时间戳)

`version` timestamp NOT NULL DEFAULT '1970-01-01 00:00:00' ON UPDATE CURRENT_TIMESTAMP,

会报错:

必须使用更大的时间,后来改为下面的默认值来解决的。

`version` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

其实是有办法使mysql5.6允许时间默认值为'0000-00-00 00:00:00' 方法:

在mysql的初始化配置文件my.ini

[mysqld]下删除sql_mode=xxxxxx中的NO_ZERO_DATE再重启mysql服务。

例如:

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

但是经过JDBC驱动包到hibernate以后,会报错:

Caused by: java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp

mysql-connector-java-5.1.38-bin.jar高版本的JDBK驱动不能转化0时间到java对象中,所以最好的办法就是不用零时间做默认值。

Mysql5.0升级到Mysql5.6

1 要升级驱动包到5.1.XX,

2 升级方言类为(在配置sessionFactory中指定方言)

<prop key="hibernate.dialect">
	org.hibernate.dialect.MySQL5InnoDBDialect
</prop>

3 关于老项目Mysql5.0升级到Mysql5.6遇到的异常:

https://www.oschina.net/question/2507499_2216974

原因分析:

2017年1月10日

进过3天的爬坑,终于解决了乐观锁  数据版本字段version造成的以上错误。

错误分析:

  <timestamp name="version" column="version"  ></timestamp>

配置的版本字段,值是由hibernate生成并保存到数据库的,而数据库的表本身建表语句使用了:

  `version` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,

数据库中表本身的时间戳版本字段(时间戳)的数据由数据库自己生成,这样就会出现每次修改数据,时间戳都被赋予了两次(其实只有第二次由数据库生成的时间戳才是真正被保存的),两者有了毫秒级的差距,实际上时间戳是数据库生成的,可是Hibernate以为自己持有的才是对的。在没有再次访问数据库获取时间戳就对数据进行修改操作时,Hibernate的时间戳和数据库的时间戳必定不同就造成了这个错误。

解决办法:

修改时间戳配置增加 generated="always"

<timestamp name="version" column="version"  generated="always"></timestamp>

表示时间戳数据由数据库提供(无论数据的创建和更新,时间戳都用数据库生成的当前时间)。

可是

 `version` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,

又会报另外一个错误,0000-00-00 00:00:00不能被解释成sql.Date。

这样必须要给timestamp 设置一个1970-01-01 00:00:01 ~ 2038 范围之内的初始值。

问题又来了:设置1970-01-01 00:00:01 数据库会报错1067 Invalid default value for 'version'

也就是数据库不允许设置这个时间戳。

所以改成了初始化时间戳为DEFAULT CURRENT_TIMESTAMP。 添加并修改数据成功。

Java连接Mysql数据库警告(升级mysql驱动包出现的警告

Establishing SSL Connection Without Server’s Identity Verification Is Not Recommend

解决办法:数据库url后面加上 ?useSSL=true

5 日志打印Hibernate的sql参数和返回

为解决本问题使用了Hibernate在Log4J中打印sql参数的功能:

前提是开启了Hibernate中的:

<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>

在log4j的配置文件中添加下面内容

#hibernate
log4j.logger.org.hibernate.type=TRACE
log4j.logger.org.hibernate.sql=TRACE

如果您受到这篇文章的帮助 请留言鼓励。