Hibernate中timestamp日期类型自动赋值且更新时不改变
最近做一个小项目,持久化层使用Hibernate
在User实体映射时遇到了一个小问题,自己做个记录
场景描述:
User实体中有一个字段 regDate(注册日期),该属性声明成 java.sql.Timestamp类型,想在插入时自动更新该属性,但后期用户在修改个人信息时,也就是执行update操作,regDate 不更新
User实体:
public class User{ private Integer id; private java.sql.Timestamp regDate; private String email; .... //get set }
User.hbm.xml
<property name="regDate" type="java.sql.Timestamp" generated="insert" update="false" insert="false"> <column name="regdate" sql-type="timestamp" ></column> </property>
创建测试类 测试
@Test public void insertUser(){ ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); IUserService userService = (IUserService) ac.getBean("userService"); User user = new User(); user.setEmail("[email protected]"); user.setNickname("IoC"); user.setPassword(MD5Util.MD5("aaa")); userService.saveOrUpdateEntity(user); }
问题:
新插入一个用户,没有问题,regDate 会自动更新成当前日期,但执行更新时 regDate值会跟着变
解决办法:
开始一直以为是实体映射出了问题,在网上搜,各有各的说法
标红的三个属性,试了好多种不同排列组合,还是不能实现想要的效果
这里随便复习一下这三个属性:
genarated:
never(默认):标明此属性值不是从数据库中生成, 也就是根本不用刷新实体类了。
insert:标明此属性值在insert的时候生成,但是不会在随后的update时重新生成。也就是只在insert情况下才会刷新实体类。
always:标明此属性值在insert和update时都会被生成。也就是在insert,update情况下都会刷新实体类。
insert="false" update="false":
设置字段为只读,该字段不会出现在 insert 和 update 语句中,也就是如下的效果
Hibernate:
update
surveypark.users
set
email=?,
password=?,
nickname=?
where
id=?
update操作,没有更新regDate 该列,但查看数据库,regDate的值还是更新了,然后才想到是不是数据库表字段类型的特性?
小结:
1.hibernate生成mysql中的timestamp字段,可以通过配置
在mysql中有timestamp类型的日期格式,又叫时间戳,只要在一个表中创建了这样的时间戳,那么只要像其中插入数据就会自动在timestamp列中加入当前的时间。
而在通过hibernate的hbm2ddl工具生成数据库表时若只是配置为TYPE=“timestamp”,那么实际生成的是datatime类型的,而不是我们想要得到的timestamp类型。
想在数据库中生成timestamp类型,就必须指定 sql-type="timestamp"
<property name="redDate" type="java.sql.Timestamp" generated="never">
<column name="regdate" sql-type="timestamp" default="CURRENT_TIMESTAMP"></column>
</property>
2.如果不想让生成的timestamp类型字段随着表中行的更新而更新
第一种(hibernate端设置)
可以在hbm.xml设置default="CURRENT_TIMESTAMP如:
<property name="redDate" type="java.sql.Timestamp" generated="never">
<column name="regdate" sql-type="timestamp" default="CURRENT_TIMESTAMP"></column>
</property>
同理如果想随着更新就设置为default="CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
default属性必须加,加完以后再查看数据库表
`regdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
第二种(数据库端设置)
重新生成相应的表并且手动设置default为CURRENT_TIMESTAMP
总结一句话,该日期能不能自动插入,和数据表字段类型 是不是 timestamp 类型有关,update时同步更新不更新和 有没有 default值有关
就到这了,吃饭