【Hibernate】——持久化对象的三种状态

来源:互联网 发布:ag网络平台能ip追杀吗 编辑:程序博客网 时间:2024/04/29 12:35
           Hibernate中的对象有三种状态,瞬时对象、持久化对象和离线对象。

           瞬时对象、持久化对象和离线对象之间的关系以及它们之间的转换如下:

               

           瞬时对象(TransientObjects):使用new 操作符初始化的对象不是立刻就持久的。它们的状态是瞬时的,也就是说它们没有任何跟数据库表相关联的行为,只要应用不再引用这些对象(不再被任何其它对象所引用),它们的状态将会丢失,并由垃圾回收机制回收。

           持久化对象(Persist Objects):持久实例是任何具有数据库标识的实例。它有持久化管理器Session统一管理,持久实例是在事务中进行操作的——它们的状态在事务结束时同数据库进行同步。当事务提交时,通过执行SQL的INSERT、UPDATE和DELETE语句把内存中的状态同步到数据库中。

           离线对象(DetachedObjects):Session关闭之后,持久化对象就变为离线对象。离线表示这个对象不能再与数据库保持同步,它们不再受Hibernate管理。

演示三种状态之间的变化

           JUnit简介:方法名的规范要以test开头,继承TestCase类。方法没有参数没有返回值,采用public修饰。建议使用断言。
想user表中添加一条记录,并对名字进行修改来演示对象的三种状态演变:
  public void testSave1(){            Session session= null;            Transaction tx= null;            User user= new User();                         try{                  session=HibernateUtils. getSession();                  tx=session.beginTransaction();                                     //Transient状态                  user.setName( "张三");                  user.setPassword( "123");                  user.setCreateTime( new Date());                  user.setExpireTime( new Date());                                     //Persistent状态                   //Persistent状态的对象,当对象的属性发生改变的时候                   //hibernate在清理缓存(脏数据检查)的时候,会和数据库同步                  session.save(user);                                    user.setName( "李四");                  tx.commit();            } catch(Exception e){                  e.printStackTrace();                  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);            }      }

           首先是建立对象与表得会话session,开启事务session.beginTransaction( ),实例化User对象,当我们User user = new User()的时候,当我们new一个对象的时候数据库时没有,所以是Transient对象,然后给user赋值,设置名称和密码以及其他属性。为对象的所有属性赋值完毕,接下来保存到会话session中,拿到session执行save(user)方法。当我们执行session的save( )方法时,这个对象就被session管理了,session中有个map,会把对象放到map中,此时的对象我们就成为persistent状态。

           接下来我们又把user中的namge属性设置为“李四”,之后提交事务。我们先在会话中存储“张三”,之后改为“李四”。try catch来捕捉异常,当执行完毕,关闭session后,对象处于detached状态。

           取得detached状态的user对象,改变这个对象的name值,user.setName("王五");之后我们再new一个新的session,通过session开启事务,之后更新操作,session.update(user),也就是把离线的对象(或脱管对象)再纳入session管理,这样就会和数据库同步,因为session.update()就把user对象纳入session管理,user对象由离线状态变为persistent状态。

注意:

           上述代码中,我们在修改名字为李四后user.setName("李四");我们并没有显示调用session的update()方法,session.update( ),而是直接提交事务tx.commit( )。会看到控制台上打印的sql语句和我们加上session.update()打印的相同。持久化对象只要更改了,在提交事务的时候就会同步,没有必要再显示调用。

           从控制台的语句中可以看出,显示发送的插入sql语句,后是update语句,首先是持久化对象user中的名字为“张三”,所以save的时候生成inset语句。此时user处于持久状态的对象,我们之后又给变了持久化对象,所以发送了一个修改语句。也就是当持久化对象发生修改时,我们再提交事务,就会把修改的全部体现出来(update语句)。

           也就是我们在提交事务的时候,在清理缓存,也就是脏数据检查(内存中变了,而数据没变),要检查哪些数据是有问题的,要保持内存和数据库的同步。所以我们数据库中添加的记录,user的名字为李四。

0 0
原创粉丝点击