【Hibernate系列】(三):三种状态之原来我不懂你

来源:互联网 发布:有趣好笑的书推荐知乎 编辑:程序博客网 时间:2024/04/30 02:28

前言

  在没有系统学习Hibernate之前,并不知道在使用Hibernate之后,持久化对象会被区分为三种状态。我的“无知”导致了其实我并怎么会用Hibernate,也就不能在项目中“知人善用”。就像是当对象处于Persistent状态,修改他的属性时,将来调用Session.commit时,就会同步到数据库。修改完属性再调用update(),其实就是多此一举。下面我们就来看看这三种状态是怎么定义的,在代码中是如何区分的。

持久化对象

  我们现在明确一下什么叫持久化对象,毕竟三种状态是用来区别持久化对象的。
  【持久化对象】:指那些要存到数据库或硬盘中的内存中的对象。如:要转化成数据库中的记录的一些实体对象。

三种状态:

【Transient】(临时):对象没持久化到数据库中,也没被纳入到Session管理。

【Persistent】(持久):纳入到Session管理。

【Detached】(脱离):对象已经持久化到数据库中,但是没有被纳入Session管理。

说明
  有没有持久化到数据库很好理,就是该对象已经转化成了数据库表中的记录。
  那什么叫做被纳入到Session管理呢?其实就是有没有被Session引用,我们知道Java的垃圾回收机制是,当一个内存中的对象没有其他引用它时,这样的对象就会在垃圾回收时,被视为垃圾,会从内存中清除。

如何确定是否被Session引用?

  调用session.save(对象);session.update(对象)的对象,或是通过session.load()返回的对象,都是被Session引用的,都是持久化状态的对象。

看看代码就知道

public void testSave1() {        Session session = null;        Transaction tx = null;        User user = null;        try {            session = HibernateUtils.getSession();            tx = session.beginTransaction();            //Transient状态            user = new User();            user.setName("zhangsan");            user.setPassword("123");            user.setCreateTime(new Date());            user.setExpireTime(new Date());            session.save(user);            //id在sava完之后产生            //调用了save之后,user对象转变为Persistent状态            //Persistent状态的对象:当对象的属性发生改变的时候            //hibernate在清理缓存(脏数据检查)的时候,会和数据库同步            user.setName("lisi");            tx.commit();            //commit之后产生两条语句            //Hibernate: insert into User (name, password, createTime, expireTime, id) values (?, ?, ?, ?, ?)            //Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?            user.setName("wangwu");//仍是持久化状态的对象,但是还没有同步到数据库中            tx = session.beginTransaction();            tx.commit();//抛异常:org.hibernate.TransactionException: Transaction not successfully started        }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);        }    }

解释
  调用commit之后,对象被同步到数据库中。在commit之后,close之前,对象还是持久化状态,只是要再次同步到数据库,必须再调用commit方法,但是直接写这一句会抛异常,需要同时先开启事务,再commit才行。
  此外:Persistent对象还可以通过get或load方法获得

public void testGet2() {        Session session = null;        try {            session = HibernateUtils.getSession();            session.beginTransaction();            //get方法加载数据,如果不存在返回null            User user = (User)session.get(User.class, "54434343434343");            System.out.println(user.getName());            session.getTransaction().commit();        }catch(Exception e) {            e.printStackTrace();            session.getTransaction().rollback();        }finally {            HibernateUtils.closeSession(session);        }    }       public void testLoad1() {        Session session = null;        try {            session = HibernateUtils.getSession();            session.beginTransaction();                     User user = (User)session.load(User.class, "4028808125534a540125534b952e0001");            System.out.println(user.getName());            user.setName("王五");            session.getTransaction().commit();        }catch(Exception e) {            e.printStackTrace();            session.getTransaction().rollback();        }finally {            HibernateUtils.closeSession(session);        }    }

总结

【1】.明确三种状态之间的区别:是否在数据库,是否在Session中
【2】.三种状态之间的转化:

  这里写图片描述

【3】.在调用commit之后,对持久化对象做的任何修改就都同步到数据库了,所以必须要懂Hibernate哦,要不然,“轻轻一碰”对象,他就“冬眠”在数据库楼!

3 0
原创粉丝点击