代码改变世界

hibernate 对象的三种状态

2012-06-27 22:17  功夫猫  阅读(976)  评论(0)    收藏  举报

Hibernate 三种状态

  Transient Object  瞬时对象

    数据库中没有数据与之一一对应,id没有纳入session的管理,随时都有可能被垃圾回收机制回收;

  Persist Object  持久化对象

    数据库中有数据与之一一对应,id纳入了session的管理;

    特点:属性与数据的改变,与数据库中保持一致;

  Detached  离线对象

    没有纳入session的管理,但数据在数据库中存在;

下面举例一一说明:

  瞬时对象:1.new出来的对象,但没有进行session.save();

       2.持久化对象调用delete()方法,变成瞬时对象;

        try {
            ts.begin();
            //new出来的对象,但未session.save(),为瞬时对象;
            User user = new User();
            user.setName("admin");

            ts.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            //session.get(),load(),find()的对象为持久化对象;
            User user =(User)session.load(User.class, 1);
            //持久化对象调用delete()方法,变成瞬时对象;
            session.delete(user);
            ts.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 

  持久化对象:1.在数据库中通过get(),load(),find()查询出来的数据肯定是持久化;

        2.瞬时的对象调用save();

        3.离线对象调用update()方法;

try {
            ts.begin();
            //直接从数据库中查出来的数据,为持久化对象;
            User user = (User)session.load(User.class, 6);
            System.out.println(user.getName());
            
            ts.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        try {
            ts.begin();
            //new出来的对象,但未session.save(),为瞬时对象;
            User user = new User();
            user.setName("admin");
            //调用session.save(),为持久化对象;
            session.save(user);
            ts.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            //手动构建离线对象,数据库中存在id为1的记录,但数据没有纳入session的管理;
            User user = new User();
            user.setId(1);
            //离线对象调用update()方法,成了持久化对象;
            session.update(user);
            ts.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 

  

  离线对象:1.手动构建离线对象;

       2.持久化对象调用evict(),clear()方法,可变为离线对象;

        try {
            //手动构建离线对象,数据库中存在id为1的记录,但数据没有纳入session的管理;
            User user = new User();
            user.setId(1);
            
            ts.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 

        try {
            ts.begin();
            //直接从数据库中get(),load(),find(),为持久化数据;
            User user = (User)session.load(User.class, 1);
            //调用evict(),clear(),close()方法,变为了离线对象;
            session.clear();
            ts.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

三者的关系图如下:

在这里要注意的一点是:update()

  很容易误认为是更新的操作,其实不是,只是将离线数据持久化的操作;

  hibernate 更新和删除的操作:先查数据,使之持久化,后进行操作;

还要要提到的是:session.flush()-将数据强制写到硬盘上;   ts.commit();

  其实commit()方法已经包含了flush()的操作。session的存在,对于数据库的查询效率有了很大的提高,不用每次都从数据库中拿,可从session中拿已有的数据;

  但对数据库的添加操作,效率依然很低。于是加入了flush()的操作;

try {
            ts.begin();
            //向数据库中添加10000条记录;
            for (int i = 0; i < 10000; i++) {
                User user = new User();
                user.setName("admin" + i);
                session.save(user);
            //每添加20条记录,便将session里的数据强制写到DB中;然后清空session;
                if (i % 20 == 0) {
                    session.flush();
                    session.clear();
                }
            }
            ts.commit();
        } catch (HibernateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 

最后指出session.clear()与session.evict()的区别:

        在于session.clear()清空的是整个session的缓存,而session.evict()可清空指定的对象;