*瞬时(transient): 数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象。
*持久(persistent): 数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)。
*脱管(detached): 数据库中有数据与之对应,但当前没有session与之关联;脱管对象状态发生改变,hibernate不能检测到
session.save(user); user.setName("new name"); tx.commit;
结果,两条语句,一条insert,一条update。 说明处于持久状态的对象,他发生变化的时候,hibernate能知道
session.save(user); user.setName("new name"); user.setBirthday(new Date()); tx.commit;
结果,两条语句,一条insert,一条update。 持久对象变化时不会立即更新数据库,而是等到commit时才做
1.Transient---瞬态的
刚new出来的时候,没有id,数据库中没有,内存(session缓存)中也没有
Teacher t=new Teacher(); t.setXXX(); t.setXXX(); t.setXXX();
这个时候,对象t就是Transient状态(没有id)
2.Persistent---持久的
有id,缓存中有.数据有里也有
session.save(t);
此时,t已经存入数据库,拥有id了,在session关闭之前,t会一直是Persistent状态,所以说save()会持久化一个对象,
3.Detached---分离(脱离管理)的
有id,缓存没有,数据库有。
session.getTransaction().commit();
提交事务之后,因为session会自动关闭,所以在内存中的session管理(缓存)已经不存在了,此时,t的是Detached状态.
这三种状态的区别:
1.有没有id
2.缓存里有没有id
3.(硬盘/数据库)里有没有id
update()需要注意的地方
1.更新Transient状态的对象会出错,但是如果更新自己指定id并且数据库存在此id记录的数据不会出错.
2.update()会更新所有的字段,即使你只想更新一个字段….
对于只更新某个字段,可以用下面的方法
a)dynamic-update节点设置
<hibernate-mapping> <class name="com.hibernate.test.entitys.Student" table="student" dynamic-update="true"> <…………> <…………> <…………> </class> </hibernate-mapping>
这样在update()的时候,程序会动态的选择更新的字段
b)使用HQL语句
Query q = session.createQuery("update Teacher t set t.name='XXXX' where t.id=1"); q.executeUpdate();
delete()----只要有id,不管是什么状态的对象,都可以删除.