当我们的应用程序通过new语句创建了一个对象,这个对象的声明周期就开始了,当不再有任何变量引用它,这个对象就结束生命周期,它占用的内存就可以被JVM的垃圾回收器回收。对于需要被持久化的Java对象,在它的生命周期中有三种状态,而且互相转化。
一、介绍
瞬时对象(TransientObjects):用new创建的对象,没有持久化,没有处于Session中;在数据库中没有与之匹配的记录。
持久化状态(PersistentObjects):纳入Session管理;在数据库中有与之匹配的记录;在属性发生改变,在清理缓存(脏数据检查)会自动和数据库同步。
离线状态(DetachedObjects):持久化对象脱离了Session的对象;在数据库中存在与之匹配的记录
二、转换
临时状态:
通过new语句刚创建一个Java对象
Session的delete()方法能使一个持久化对象或游离对象转变为临时对象
持久化状态:
Session的save()方法把临时对象转变为持久化对象
Session的load()或get()方法返回的总是处于持久化状态
Session的find()方法返回的List集合中存放的是持久化对象
Session的update()、saveOrUpdate()和lock()方法使游离对象转变为持久化对象
当一个持久化对象关联一个临时对象,在允许级联保存的情况下Session在清理缓存时会把这个临时对象转变为持久化对象。
游离对象(持久化对象转变为游离对象)
当调用Session的Close方法时,Session的缓存被清空,缓存中的所有持久化对象都变为游离对象。
Session的evict()方法能够从缓存中删除一个持久化对象,使她变为游离状态。
注:
游离状态和临时状态相同点:都不被Session管理,无法保证它们的属性变化与数据库保持同步。区别在于:前者是由持久化对象转变过来的,因此可能在数据库中还存在对应记录,而后者在数据库中没有对应记录。
三、实例
在操作了hibernate的方法如Save()等后,并没有直接生成sql语句,去操作数据库,而是把这些更新存入Session中,只有Session缓存更新时,底层的sql语句才能执行,数据存入数据库。
1、工具类:
当我们建立Session时都要实例化SessionFactory,所以我们将重复代码进行封装,如打开Session、关闭Session。
public class HibernateUtils {
private static SessionFactory factory;
static{
try {
//默认读取的是hibernate.cfg.xml
Configuration cfg = new Configuration().configure();
//建立sessionFactory
factory = cfg.buildSessionFactory();
} catch (Exception e) {
e.printStackTrace();
}
}
//开启session
public static Session getSession(){
return factory.openSession();
}
//关闭session
public static void closeSession(Session session){
//判断是否为空
if(session!=null){
//判断是否是打开状态再进行关闭
if(session.isOpen()){
session.close();
}
}
}
}
public void testSave3(){
Session session=null;
Transaction tx=null;
User user=null;
try {
session = HibernateUtils.getSession();
//开启事务
tx=session.beginTransaction();
//对象中赋值(Transient状态)
user=new User();
user.setName("高晓青");
user.setPassword("123456");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
//Persistent状态
//Persistent状态的对象,当对象的属性发生改变的时候
//hibernate在清理缓存(脏数据检查)时,会和数据库同步
session.save(user);
user.setName("燕坤");
tx.commit();
} catch (Exception e) {
e.printStackTrace();
if(tx!=null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
}
(1)建立对象与表的Session,开启事务,实例化对象(new一个对象数据库是没有的,所以是Transient对象)
(2)为对象进行赋值,接下来保存到session中(对象就被session管理了,此时对象为Persistent状态)
(3)再次设置对象属性后提交事务,关闭session后,对象处于detached状态
3、Detach状态:
public void testSave4(){
Session session=null;
Transaction tx=null;
User user=null;
try {
session = HibernateUtils.getSession();
//开启事务
tx=session.beginTransaction();
//对象中赋值(Transient状态)
user=new User();
user.setName("高晓青");
user.setPassword("123456");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
//Persistent状态
//Persistent状态的对象,当对象的属性发生改变的时候
//hibernate在清理缓存(脏数据检查)时,会和数据库同步
session.save(user);
user.setName("燕坤");
tx.commit();
} catch (Exception e) {
e.printStackTrace();
if(tx!=null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
//detached状态
user.setName("依依");
try {
session=HibernateUtils.getSession();
session.beginTransaction();
//将detached状态的对象重新纳入session管理,表位persistent状态的对象
//persistent状态的对象,在清理缓存时会和数据库同步
session.update(user);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
(1)取得detached状态的user对象,改变这个对象的属性
(2)开启session和事务,把离线的对象再纳入session管理,可以和数据库进行同步,user对象由离线状态转变为Persistent状态