在学习SSM框架的过程中需实现如下过程:
Key1:需要通过mybatis向数据库插入一条记录,且此记录包含timestamp类型字段。假设字段为[id,name,tel,pay_time],第四个为timestamp类型。
Key2:插入记录时没有为pay_time字段提供数值,假设理想的插入MySQL语句为INSERT INTO 表名 VALUES (1,张三,13011111111)
。
Key3:通过框架执行插入语句后,虽然没有指定pay_time字段的数值,但pay_time字段会自动插入当前时间。
然而实际情况如下:
1.如果pay_time字段属性设置为默认非空时,即TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
,通过框架执行插入语句后,程序马上报错不允许null值插入。
2如果pay_time字段属性设置为默认空值时,即TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
,通过框架执行插入语句后,程序不会报错,但是数据库里pay_time字段的数值为null,无法达到自动插入当前时间的需求。
3.但是如果手动通过CMD命令行执行插入语句,无论pay_time字段设置是否为null,数据库都会为pay_time字段插入当前时间。
原因:
通过SSM框架插入数据时,如果没有为字段提供数值,dao层会默认提供一个null值,比如本例中理想的插入语句为INSERT INTO 表名 VALUES (1,张三,13011111111)
,但是经过框架的处理后实际的插入语句为INSERT INTO 表名 VALUES (1,张三,13011111111,null)
。
所以手动通过CMD命令行执行插入语句时,会自动插入当前时间,而经框架处理后的插入语句为pay_time字段提供了null值,引发了前述等问题。
处理办法:
1.打开MySQL的my.ini文件在[mysqld]
下添加explicit_defaults_for_timestamp=OFF
,然后重启MySQL数据库,如图:
2.把timestamp类型字段属性设置为TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
这样当给timestamp类型字段插入一个null值时,程序不会报错,同时数据库会自动给timestamp类型字段插入当前时间值。
PS:
1.explicit_defaults_for_timestamp详细相关可参考
2.修改timestamp类型字段属性的语句:
①ALTER TABLE 表名
CHANGE 字段名
字段名
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;(在创建新记录时自动插入当前时间)
②ALTER TABLE 表名
CHANGE 字段名
字段名
TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP;(在修改现有记录时自动插入当前时间)
③ALTER TABLE 表名
CHANGE 字段名
字段名
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;(在创建新记录和修改现有记录时都字段插入当前时间)
3.当数据库里已经存在某一条记录且timestamp类型字段是null值,此时再去把timestamp类型字段属性设置为NOT NULL,数据库会报错,必须先把含有null值的记录删除再设置timestamp类型字段的属性
4.在Navicat修改timestamp类型字段属性的方法,默认值输入CURRENT_TIMESTAMP
,并勾选根据当前时间戳更新
5.在Linux系统下需修改的文件为my.cnf