Hibernate持久化对象有如下三种状态:
1 . 瞬态:对象由new操作符创建出来之后,还未与Hibernate Session相关联,对应的数据表中没有该对象对应的数据。瞬态对象不会被持久化到数据库中,也不会被赋予持久化标识,如果程序中失去了对瞬态对象的引用,则该对象会被垃圾回收器处理掉。使用Hibernate Session可以将其持久化
2 .持久化:持久化对象在数据表中有对应的记录,并且有持久化标识。持久化的对象可以使刚刚被保存的,也可以是刚刚被加载的。无论哪一种,持久化对象都必须与指定的Hibernate Session关联。Hibernate会检测到持久化对象的改动,在当前操作执行完成时将改动过的数据写回数据库,而不需要在执行update。
3 . 脱管:如果某个对象曾经处于持久化状态,但随着与之关联的Session的关闭,该对象就会变为托管状态。此时数据表中依然存在与之对应的记录。这时对于托管对象的引用依然有效,可以对该托管对象进行修改。如果重新让托管对象与某个Session相关联,这个托管对象又会重新变为持久化状态,而且在托管状态进行的修改不会丢失,也能被写入数据库。
Hibernate持久化对象的状态转换图:
瞬态的对象转换为持久化状态的方法,Serializable save(Object obj) ; Serializable save(Object obj , Object id);
void persist(Object obj) ; void persist(Object obj ,Object id);
根据主键加载持久化实体: Object load(Object.class , Serializable id ) ; Object get (Object.class , Serializable id )
Object find(Object.class , Serializable id )
save() 与 persist() 方法的区别与联系:
这两个方法都是用于将对象转换为持久化状态,并将其属性保存到数据库,Hibernate之所以 提供一个与save()功能差不多的persist()方法,一方面是为了照顾JPA的习惯用法,另一方面这两个方法之间还有一个区别:使用save()方法保存持久化对象时,该方法返回该持久化对象的标识属性,也就是对应记录的主键值,而persist()方法的返回值为空,。正式因为save()方法需要在执行时立即返回一个主键值,所以程序执行save方法时会立即将持久化的数据插入到数据表中,而persist方法则保证在事务外部调用时,并不会立即执行insert语句,这个功能是很有用的,尤其是在需要封装一个长会话流程时,persist方法显得尤为重要。
load() 和 get()方法的区别与联系:
这两个方法都是用于在数据库中根据数据表和主键来加载持久化实例,它们都是先在hibernate缓存中查找,如果没有找到对应的对象,则查询hibernate的二级缓存,再找不到则会发送sql语句 。这两个方法的主要区别在于是否延迟加载,当hibernate配置文件的lazy属性为true时,使用load方法加载对象,并不会马上执行select 语句查找数据,而是根据主键先生成一个代理对象,当需要访问其他属性时才真正的去访问数据库,当对应的数据不存在时,将会抛出ObjectNotFoundException异常。如果在某个对象中创建于另一个对象的关联,这种延迟加载方式将会提高程序的执行效率。而get方法执行时不会生成代理对象,而是直接执行select语句访问数据库,如果没有对应的记录,将会返回null。
find()方法不推荐使用。
更新持久化状态的实体:
<span style="font-size:14px;">User u = session.load(User.class, id);
u.setUsername("张三");
session.flush();</span>
程序对持久化实体做的修改会直接被保存到数据库,执行u.set..()方法时便会执行update语句,不需要调用update方法将修改持久化。
更新脱管实体:
<span style="font-size:14px;">User u = session.load(User.class, id);
//关闭Session
session.close();
//托管状态下的持久化对象
u.setName("张三");
//打开新的Session
Session newsession=...;
//保存脱管对象的修改,并重新变为持久化状态
session.update();</span>
update() 和 updateOrSave()的区别:
当使用update保存程序对持久化对象做的修改时,如果不清该对象是否被持久化过,可以使用updateOrSave(),这个方法会判断该对象是否被持久化过,如果未被持久化过,则执行save()方法,否则执行update();
删除持久化实体:
<span style="font-size:14px;">User u = session.load(User.class, id);
session.delete(u);</span>
删除持久化对象后,该对象会变为瞬态,如果程序失去了对该对象的调用,则会被垃圾回收器处理掉。