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

前言

  在没有系统学习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哦,要不然,“轻轻一碰”对象,他就“冬眠”在数据库楼!

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值