hibernate三种状态的讲解

2019-03-28 12:14|来源: 领悟书生

最近学习了一下hibernate(hibernate三种状态的讲解),看到网上有一篇写得还挺不错,就转载下来,自己写的不一定比人家总结得好,还结合了孔浩老师上课的案例代码,下面是详细内容:


下面是转自:http://www.blogjava.net/asktalk/archive/2006/01/18/28548.html的一篇文章

在Hibernate中有三种状态,对它的深入理解,才能更好的理解hibernate的运行机理,刚开始不太注意这些概念,后来发现它是重要的。对于理解hibernate,JVM和sql的关系有更好的理解。对于需要持久化的JAVA对象,在它的生命周期中有三种状态,而且互相转化。

1,  临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;

2,  持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;

3,  游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。
特点:已经持久化,但不在Session
缓存中。处于此状态的对象叫游离对象;

×√

临时状态

(Transient)

持久化状态

(Persistent)

游离状态

(Detached)

是否处于Session缓存中

×

×

数据库中是否有对应记录

×

状态转换图,结束官方的和转载作者的

hibernate3.gif


游离对象和临时对象异同:

两者都不会被Session关联,对象属性和数据库可能不一致;

游离对象有持久化对象关闭Session而转化而来,在内存中还有对象所以此时就变成游离状态了;

Hibernate和SQL的关系:

在操作了hibernate的方法如save()等后,并没有直接生成sql语句,去操作数据库,而是把这些更新存入Session中,只有Session缓存要被更新时,底层的sql语句才能执行,数据存入数据库;

下面举例说明:
一,Session.save(user)运行机理。
1,把User对象加入缓存中,使它变成持久化对象;
2,选用映射文件指定的标识生成ID;
3,
在Session清理缓存时候执行:在底层生成一个insert sql语句,把对象存入数据库;

注意:在你执行Session.save(user)后,在Session清理缓存前,如果你修改user对象属性值,那么最终存入数据库的值将是最后修改的值;此过程中ID不能被修改;

二,Session.delete(user)运行过程。
如果user是持久化对象,则执行删除操作,同样底层数据库的执行条件是:
在Session清理缓存时候;
如果user是游离对象:
1,将user对象和Session关联,使之成为持久化对象;
2,然后按照user 是持久化对象的过程执行;


下面是孔浩老师讲课的代码:

package org.zttc.itat.test;
  
import java.text.SimpleDateFormat;
  
import org.hibernate.Session;
import org.junit.Test;
import org.zttc.itat.model.User;
import org.zttc.itat.util.HibernateUtil;
  
public class TestStatus {
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    @Test
    public void testTransient() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            User u = new User();
            u.setBorn(sdf.parse("1976-2-3"));
            u.setUsername("zxl");
            u.setNickname("赵晓六");
            u.setPassword("123");
            //以上u就是Transient(瞬时状态),表示没有被session管理并且数据库中没有
            //执行save之后,被session所管理,而且,数据库中已经存在,此时就是Persistent状态
            session.save(u);
              
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testPersistent01() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            User u = new User();
            u.setBorn(sdf.parse("1976-2-3"));
            u.setUsername("zxq");
            u.setNickname("赵晓七");
            u.setPassword("123");
            //以上u就是Transient(瞬时状态),表示没有被session管理并且数据库中没有
            //执行save之后,被session所管理,而且,数据库中已经存在,此时就是Persistent状态
            session.save(u);
            //此时u是持久化状态,已经被session所管理,当在提交时,会把session中的对象和目前的对象进行比较
            //如果两个对象中的值不一致就会继续发出相应的sql语句
            u.setNickname("赵晓其");
            //此时会发出2条sql,一条用户做插入,一条用来做更新
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testPersistent02() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            User u = new User();
            u.setBorn(sdf.parse("1976-2-3"));
            u.setUsername("zxq");
            u.setNickname("赵晓八");
            u.setPassword("123");
            session.save(u);
            u.setPassword("222");
            //该条语句没有意义
            session.save(u);
            u.setNickname("赵晓吧");
            //没有意义
            session.update(u);
            u.setBorn(sdf.parse("1988-12-22"));
            //没有意义
            session.update(u);
            //持久化状态(缓存中),事务提交的时候,才执行语句
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testPersistent03() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            User u = new User();
            u.setBorn(sdf.parse("1976-2-3"));
            u.setUsername("zxq");
            u.setNickname("赵晓九");
            u.setPassword("123");
            session.save(u);
            /*
             * 以下三条语句没有任何意义
             */
            session.save(u);
            session.update(u);
            session.update(u);
            u.setUsername("zxj");
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testPersistent04() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            //此时u是Persistent
            User u = (User)session.load(User.class, 10);
            //由于u这个对象和session中的对象不一致,所以会发出sql完成更新
            u.setUsername("aaa");
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testPersistent05() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            //此时u是Persistent
            User u = (User)session.load(User.class, 10);
            session.getTransaction().commit();
            session.beginTransaction();
            u.setUsername("123");
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testPersistent06() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            //此时u是Persistent
            User u = (User)session.load(User.class, 11);
            u.setUsername("123");
            //清空session
            session.clear();
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testDetach01() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            User u = new User();
            u.setId(10);
            u.setNickname("abc");
            //当执行save的时候总是会添加一条数据,此时id就会根据Hibernate所定义的规则来生成(10是无效的)
            session.save(u);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testDetach02() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            User u = new User();
            u.setId(10);
            //完成update之后也会变成持久化状态
            session.update(u);
            u.setBorn(sdf.parse("1998-12-22"));
            u.setNickname("aaa");
            u.setUsername("111");
            //会发出一条sql
            session.update(u);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testDetach03() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            User u = new User();
            u.setId(10);
            //完成update之后也会变成持久化状态
            session.update(u);
            u.setBorn(sdf.parse("1998-12-22"));
            u.setNickname("aaa");
            u.setUsername("111");
            //会抛出异常
            u.setId(333);
            //会发出一条sql
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testDetach04() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            User u = new User();
            u.setId(10);
            //现在u就是transient对象
            session.delete(u);
            //此时u已经是瞬时对象,不会被session和数据库所管理
            u.setNickname("abc");
            //只会发出一条delete语句
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testDetach05() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            User u = new User();
//          u.setId(110);
            u.setNickname("abc");
            //如果u是离线状态【数据库中有,有ID就认为是,但session缓存中没有】就执行update操作,如果是瞬时状态就执行Save操作
            //但是注意:该方法并不常用
            session.saveOrUpdate(u);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
      
    @Test
    public void testDetach06() {
        Session session = null;
        try {
            session = HibernateUtil.openSession();
            session.beginTransaction();
            //u1已经是持久化状态
            User u1 = (User)session.load(User.class, 11);
            System.out.println(u1.getNickname());
            //u2是离线状态
            User u2 = new User();
            u2.setId(11);
            u2.setPassword("12223");
            //此时u2将会变成持久化状态,在session的缓存中就存在了两份同样的对象,在session中不能存在两份拷贝,否则会抛出异常
//          session.saveOrUpdate(u2);
            //merge方法会判断session中是否已经存在同一个对象,如果存在就将两个对象合并
            session.merge(u2);
            //最佳实践:merge一般不用
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            if(session!=null) session.getTransaction().rollback();
        } finally {
            HibernateUtil.close(session);
        }
          
    }
}


本文链接:hibernate三种状态的讲解,领悟书生整理笔记,转载请注明出处http://www.656463.com/article/394

相关问答

更多
  • 输入设备 存储设备 输出设备 这三种! 鼠标键盘等 硬盘,内存,cpu等 显示器,音箱等
  • Struts+Spring+Hibernate 整合教程 v1.0 开源传万世,只因你我皆参与! While (isAlive()) { goodGoodstudy(); dayDayUp(); } 日期: 2008-01-06 PDF文档下载地址: http://www.jacken.com.cn/struts-spring-hibernate-_-integration.yy
  • 瞬时态:简单的说就是你在程序里面new一个对象,还没有和session关联 持久态:对象和session有了关联,对象处于hibernate框架管理中 游离态:在持久态的情况下,对象和session失去了关联,比如session.close()或session.flush() 后,即游离态,但数据已经存储到了数据库
  • 有限状态机(以下用FSM指代)是一种算法思想,简单而言,有限状态机由一组状态、一个初始状态、输入和根据输入及现有状态转换为下一个状态的转换函数组成。在Gof的23种设计模式里的state模式是一种面向对象的状态机思想,可以适应非常复杂的状态管理。
  • (1)瞬态:表示该实体对象在内存中是自由存在的,也就是说与数据库中的数据没有任何的关联即,该实体从未与任何持久化上下文联系过,没有持久化标识(相当与主键)。瞬态实体的特征有: 与数据库中的记录没有任何关联,也就是没有与其相关联的数据库记录 与Session没有任何关系,也就是没有通过Session对象的实例对其进行任何持久化的操作。 (2)持久态:指该实体对象处于Hibernate框架所管理的状态,也就是说这个实体对象是与Session对象的实例相关的。处于持久态的实体对象的最大特征是对其所作的任何变更操作 ...
  • 并非所有的图形用户界面都表示为全角。 这就是为什么使用以下其中一种方法会更加清晰: 1. 收音机 2. 下拉 3. 列表框 I have decided to use CheckBoxList anyway, since I need two states accessible by the user, and a third one not accessible by the user but to display inconsistencies. The way I have solved this i ...
  • 关于这个问题的代码项目有一篇很好的文章。 三态TreeView控件 There's a nice article on code project about just this. Tri-State TreeView Control
  • 是的,但你需要创建一些额外的张量,如下所示: # creates 'both inactive' ground truth flag tensor both_inactive_gt = tf.cast( 1.0 - tf.reduce_sum( labels, 1 ), tf.bool ) threshold = 0.5 # whatever threshold you want to use # two steps to create prediction flag tensor # First: ...
  • 我花了一天时间开发自己的自定义控件。 感谢那些花时间看的人,更感谢那些建议。 I've spent the day developing my own custom control. Thanks for those that took the time to look and more thanks to those for suggestions.