瞬时 (Transient ) : 通常new 创建对象(持久化类),未与Session关联
持久 (Persistent) : 在数据库存在对应实例,拥有持久化标识OID, 与Session关联(受session管理)
脱管 (Detached):当Session关闭后,持久状态对象与Session断开关联,称为脱管对象,此时也持有OID
编写hbm映射
编写测试类:
//po状态
@Test
public void testSaveForPO(){
//瞬时态:new一个对象
//特点:未与session关联,没有OID,数据库没有该数据
Customer customer = new Customer();
customer.setName("Rose");
customer.setAge(18);
Session session = HibernateUtils.openSession();
session.beginTransaction();
//保存操作
//持久态
//特点:与session关联,“有OID,数据库有对应数据”
//立刻发出insert语句,进行抢占数据库的主键ID,并且hb会将该id返回给po
session.save(customer);
session.getTransaction().commit();
//脱管态
//特点:与session失去联系,有OID,“数据库有对应数据”
session.close();//session关闭
}
三种状态的区别分析:
持久态和瞬时态、脱管态:容易区别,持久态主要特点是与Session关联,而且数据库中有对应记录、拥有OID,因此,只要与session关联的就是持久态。
瞬时态和脱管态:相同点是都和Session没关联,不同点是瞬时态没有OID,而脱管态有OID。
通过上述的分析,发现,瞬时态和脱管态对象就差一个OID,那么瞬时态的对象中给主键ID属性赋值后就是脱管态了么?
未必!
首先,需要区分持久化标识OID和对象中主键ID属性的关系:
l 在持久化之前,虽然有ID属性,但数据库中没有对应的数据,那么此时OID是null;
l 在持久化之后,这个ID属性值被插入数据库中当主键了,数据库中有对应的数据了,此时OID就有值了,而且与主键值保持一致性,比如类型、长度等。
因此:OID和PO对象中主键ID属性的区别就是:数据库存在不存在,如果存在就是OID,如果不存在,那就是个ID属性而已。
瞬时态和脱管态的区别扩展:
l 脱管态对象:有持久化的标识oid,并且在数据库中存在。
l 瞬时态对象:无持久化标识oid,或者有id但在数据库中不存在的(自然主键情况)。
例如:
Customer对象具有Id属性值,如果数据库中不存在,则该对象还是瞬时态对象,如果数据库中存在,则认为是脱管态的。
【三者的区别最终总结】:
对于三者:在session中存在的,就是持久化对象,不存在的就是瞬时或脱管对象。
对于瞬时和脱管对象:有oid(持久化标识)的就脱管对象,没有的就是瞬时对象。
持久化对象状态转换图(官方规范):
分解分析(对象的获取和如何转换到其他状态):
n 瞬时对象:
如何直接获得 --- new 出来
转换到持久态 ---- save、saveOrUpdate 保存操作
转换到脱管态 ---- setId 设置OID持久化标识(这个id是数据库中存在的) (不是规范中的)
n 持久对象
如何直接获得 ---- 通过session查询方法获得 get、load、createQuery、createCriteria
转换到瞬时态 ---- delete 删除操作 (数据表不存在对应记录 )(其实还有id,只是不叫OID)
转换到脱管态 ---- close 关闭Session, evict、clear 从Session清除对象
n 脱管对象
如何直接获得 ----- 无法直接获得 ,必须通过瞬时对象、持久对象转换获得
转换到瞬时态 ---- 将id设置为 null,或者手动将数据库的对应的数据删掉
转换到持久态 ---- update、saveOrUpdate、lock (对象重新放入Session ,重新与session关联)