站在持久化的角度,hibernate将对象分为四种状态。
1.持久化状态
OID不为空,缓存中存在记录,数据库中也有响应的记录
2.临时状态
在使用代理主键的情况下,OID通常为null 不在session的缓存中 数据库中没有相应的记录
3.游离状态
OID不为null ,不在session的缓存中,数据库中可能还保留有响应的记录
4.删除状态
数据库中没有和其OID相同的记录,不在session的缓存中
1.save()方法
save方法可以将临时对象转换为持久化对象
可以看到在save方法前后,分配了对象的OID
注意:在save方法之前设置的对象的ID时无效的
并且持久化对象的ID不能被修改,因为hibernate就是通过ID和数据表中的记录进行对应的,如果想要修改对象的ID,那么数据库记录与对象的映射关系将会被破坏
persist()方法
persist方法和save()方法很类似都会发送一条insert语句执行插入操作
二者区别:save方法在执行前运行对象存在ID,执行后会将其覆盖,而persist方法在保存有ID的对象时会抛出异常。
get方法和load方法
两个方法乍一看好像没有什么区别,并且都发送了select语句。但是我们如果打印一下对象的类型就明白了
我们发现load方法返回的并不是News类型的对象,实际上它是hibernate生成的代理对象。
所以实际上get是立即加载,而load是延迟加载。
其次get方法在获取数据库中不存在的记录时会返回null值,而load方法会抛出异常。
如果使用load方法时,在使用实例化对象之前session关闭了,那么会抛出懒加载异常
update方法
session 的update方法使一个游离对象变为持久化对象。
如果需要跟新一个持久化对象,不需要显示调用update方法。
因为在执行transaction的commit方法之前会执行session的flush方法,会发送update语句。
什么时候用update方法呢?
在一个session缓存中的持久化对象,对于另一个session来说就是游离对象,因为另一个session中没有当前对象的引用,但是数据库表确实存在记录,所以就需要update方法将游离对象变为持久化对象。
如果对数据库中不存在的进行update操作,那么会抛出异常
如果session缓存中已经存在了某条记录的缓存对象,update另一个相同OID的对象时,将会抛出异常。
saveOrUpdate方法
session的savaeOrUpdate方法,如果对象的OID为null,则调用save方法,否则调用update方法
其他用法同上。
特别的如果在.hbm.xml文件的id元素中设置了unsaved-value属性,那么该属性指定ID值的对象被视为临时对象。
delete方法
删除一个持久化对象或游离对象
只要数据库表中有和OID所对应的记录,就会执行delete操作,如果没有则会抛出异常。
注意看控制台打印的语句,delete语句是在事务提交flush缓存时发送的,所以执行delete方法后OID不为空,所以如果此时对news对象执行saveOrUpdate方法,因为OID不为空则会执行update,而数据库中又没有响应的记录,那么则会抛出异常。
因此可以设置hibernate配置文件的一个属性
可以使删除对象的OID变为null