核心对象+持久对象全析(2)

来源:互联网 发布:dota2能在mac上玩吗 编辑:程序博客网 时间:2024/05/17 23:39

一、状态解析


      Hibernate的持久对象主要分为三个状态,Transient、Persistent、Detached,其中Transient称为瞬态,没有被数据库管理,Hibernate没有为对象分配id,在数据库中没有对应的行,一般在new出一个对象后转化为瞬态;Persistent称为持久化,此时已经被Session管理,Hibernate为对象分配了一个id(该id可以使用其它方法手动或者自动分配,id的类型可以在User.hbm.xml中配置),在数据库中已经有了对应的一行,在调用session的save方法后会提交到数据库中;Detached称为脱管对象,此时已经将修改同步到了数据库中,它有Hibernate分配的id,但是此时的id是在持久化状态分配的,在编程时此状态的对象往往已经不受session管理,如果想要再次修改可以再次创建一个session,然后管理对象。Transient、Detached的对象如果长时间不使用的话,会在某一时间段被Java的垃圾回收装置进行回收。

  1、Transient:数据库中没有,没有被Session管理


       从Hibernate的体系结构图中不难看出,对象的瞬态是在应用程序中完成的,当对象被创建后即转变为瞬态,它还没有持久化的过程,也就是说并没有持久化标示(id号,Hibernate在创建持久化对象时都会为该对象指定一个id标示,保证唯一性)。瞬态的对象如果没有任何的操作的话,会在某一时刻消亡,并被Java的垃圾回收器回收。

      事例演示:在SessionTest中添加一个名为testSave1的方法,代码如下:

  1. public void testSave1(){  
  2.     Session session=null;  
  3.     Transaction tx = null;  
  4.     try{  
  5.         session=HibernateUtils.getSession();  
  6.         //开启事务  
  7.         tx= session.beginTransaction();  
  8.           
  9.         //Transient状态  
  10.         User user=new User();  
  11.         user.setName("zhangsi");  
  12.         user.setPassword("123");  
  13.         user.setCreateTime(new Date());  
  14.         user.setExpireTime(new Date());  
  15.           
  16.     }catch(Exception e){  
  17.         e.printStackTrace();  
  18.         if(tx != null){  
  19.             tx.rollback();  
  20.         }  
  21.     }finally{  
  22.         HibernateUtils.closeSession(session);  
  23.     }  
  24.       
  25.     //detached状态  
  26. }  

     在save方法处设置断点,运行调试,输出结果如下图:

   

   2、Persistent:数据库中有,被session管理


        一个瞬态的对象操作完成后需要保存操作,这时候调用save或者其他保存方法时即被转换为持久对象,这时候Hibernate给该对象创建一个持久化标示,并且可能在数据库中有了一个对应行,而且该标示与Java标示(该值表示对象在内存的位置)等价。
       另外一个没有被创建的对象同样可以使用其它的方法来直接转换到该状态,如上图的get、load等方法。persistent状态的对象若发生了改变,则在清理内存时或者在脏数据检查时会把改变同步到数据库中,那么此时会生成两条语句,分别为insert和update。在SessionTest中添加saveTest2方法,测试持久态


  1. public void testSave2(){  
  2.         Session session=null;  
  3.         Transaction tx = null;  
  4.         try{  
  5.             session=HibernateUtils.getSession();  
  6.             //开启事务  
  7.             tx= session.beginTransaction();  
  8.               
  9.             //Transient状态  
  10.             User user=new User();  
  11.             user.setName("zhangsi");  
  12.             user.setPassword("123");  
  13.             user.setCreateTime(new Date());  
  14.             user.setExpireTime(new Date());  
  15.               
  16.             //persistent状态  
  17.             //persistent状态的对象,当对象的属性发生改变的时候  
  18.             //Hibernate在清理缓存(脏数据检查)的时候,会和数据库同步  
  19.             session.save(user);  
  20.             user.setName("lisi");  
  21.               
  22.             //可以显示的调用udpdate方法,因为此时为持久状态,调用udpate没有什么意义  
  23.             session.update(user);  
  24.               
  25.             tx.commit();  
  26.               
  27.         }catch(Exception e){  
  28.             e.printStackTrace();  
  29.             if(tx != null){  
  30.                 tx.rollback();  
  31.             }  
  32.         }finally{  
  33.             HibernateUtils.closeSession(session);  
  34.         }  
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. }  

       调用save方法后进入的持久态,此时的为user对象添加了id标识:
        方法执行完成后会向数据库中添加新的一条信息,细心的童鞋可以看出方法中调用了两次setName方法,最后结果是什么呢,查看mysql中的表可以看到:

      数据库中添加的最后信息是lisi,所以它最后执行了更新操作,此时在控制台中会打印两条sql语句,分别为insert和update语句。
      Note:在提交事务或者关闭Session前,会调用Session的flush方法对每个更改进行操作。

 3、Detached:数据库中有,没有被session管理


       脱管状态下的对象其实已经被映射到了数据库中,只不过此时还没有被垃圾回收期回收,此时的对象拥有持久化标识,该标识对应着数据库中的一行,但是不保证该标识与Java标识对应。
       在SessionTest类中添加testSave3方法,测试Detached状态下对象和数据库,代码如下:


  1. public void testSave3(){  
  2.         Session session=null;  
  3.         Transaction tx = null;  
  4.         User user=null;  
  5.         try{  
  6.             session=HibernateUtils.getSession();  
  7.             //开启事务  
  8.             tx= session.beginTransaction();  
  9.               
  10.             //Transient状态  
  11.             user=new User();  
  12.             user.setName("zhangsi");  
  13.             user.setPassword("123");  
  14.             user.setCreateTime(new Date());  
  15.             user.setExpireTime(new Date());  
  16.               
  17.             //persistent状态  
  18.             //persistent状态的对象,当对象的属性发生改变的时候  
  19.             //Hibernate在清理缓存(脏数据检查)的时候,会和数据库同步  
  20.             session.save(user);  
  21.             user.setName("lisi");  
  22.               
  23.             tx.commit();  
  24.               
  25.         }catch(Exception e){  
  26.             e.printStackTrace();  
  27.             if(tx != null){  
  28.                 tx.rollback();  
  29.             }  
  30.         }finally{  
  31.             HibernateUtils.closeSession(session);  
  32.         }  
  33.           
  34.         //detached状态  
  35.         user.setName("wangwu");  
  36.         try{  
  37.             session=HibernateUtils.getSession();  
  38.             session.beginTransaction();  
  39.               
  40.             //将detached状态的对象重新纳入session管理  
  41.             //此时将变为persistent状态的对象  
  42.             //persistent状态的对象,在清理缓存时会和数据库同步  
  43.             session.update(user);  
  44.             session.getTransaction().commit();  
  45.         }catch(Exception e){  
  46.             e.printStackTrace();  
  47.             session.getTransaction().rollback();  
  48.         }finally{  
  49.             HibernateUtils.closeSession(session);  
  50.         }  
  51.           
  52. }  

      执行完成后,查看数据库中信息,如下图:

     分析执行结果,不难发现它最后完成的是更新操作,不同的是detached状态下的对象必须重新定义新的Session对象,因为Session对象线程不安全,容易出错。

结语


       上文主要讨论分析了Hibernate持久对象在整个声明周期的状态转化过程,这几种状态的相互转化使得关系模型和对象模型进行了紧密的关联,另外在使用配置文件来管理这几种状态,这样使得Hibernate的操作简单,并且功能强大。上文只是针对持久对象的几种状态做了初步的解析,另外还有状态之间的转化方法将会在下篇文章讨论。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝吃手上瘾拒绝吃奶粉吃奶怎么办 2岁宝宝特别粘人爱哭怎么办 3岁半宝宝突然说话口吃怎么办 2岁3个月宝宝突然说话结巴怎么办 一位特爱说话爱玩的高中生怎么办 猫5天不吃不喝躲起来该怎么办 两个月的小家猫睡觉要黏人睡怎么办 成年的儿子不听话做父母要怎么办 听到孩子上课又不听话想揍他怎么办 18个月小孩脾气很犟怎么办 烦自己的孩子想弄死他怎么办 楼道经常有小孩在门口恶作剧怎么办 2岁宝宝咳嗽咳吐了怎么办 不小心把鱼刺吃下去该怎么办 儿子在学校被老师甩耳光我该怎么办 家长诬陷老师打她家孩子耳光怎么办 一岁宝宝总觉得有痰怎么办 一岁宝宝感冒咳嗽有痰怎么办 哭的时候踹不过气来应该怎么办 孩子在幼儿园被老师罚站怎么办 孩子屁股打肿了又红又紫怎么办 生完孩子两个月一直浑身疼怎么办 宝宝被蚊子叮咬后红肿硬怎么办 小孩屁股青一块紫一块打的怎么办 小孩的手被鞭子抽红了怎么办 孩子每次写作业都要挨打挨骂怎么办 儿子四岁脾气特别大怎么办呢 月子里屁股被开水烫了怎么办 学生打闹家长只找老师责任怎么办 两个学生打闹受伤的孩子家长怎么办 小孩学习不好做家长的该怎么办 对学习不入门的小孩家长该怎么办 孩子老做作业发神上课不专心怎么办 儿子成绩考得差不专心未来怎么办 五年级学生写字慢又丑怎么办 宝宝上课坐不住不听老师话怎么办 三岁宝宝特调皮打他还还手怎么办 怀孕40天不知道喝酒了怎么办 怀孕四十天的时候喝酒抽烟了怎么办 宝宝怀孕三十天左右喝酒了怎么办 两个人都喝酒了意外怀孕怎么办