Hibernate 中对象的三种状态及其转化

Hibernate 中对象的三种状态及其转化
瞬时状态(transient):刚刚用new语句建立,还没有被持久化,不处于session的缓存中。
持久化对象(persistent):已经被持久化,加入到session的缓存中。
游离状态(detached):已经被持久化,但不再处于session的缓存中。


图示:

 

瞬时状态:

数据库中不存在的,同时也不在hibernate session中管理的对象(new 的对象):

User user = new User();

瞬时对象可以通过save 方法,转变为持久态对象,此时 hibernate会发出一条SQL语句

  User user = new User();
        user.setName("han");
        user.setPassword("123456");
        user.setStatus("A");
        user.setBirthday(date);
        Configuration config = new Configuration().configure(); // Hibernate框架加载hibernate.cfg.xml文件
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();
        //开启事务
        session.beginTransaction();
        session.save(user);
        //事务提交
        session.getTransaction().commit();
        session.close();
        sessionFactory.close();
结果:Hibernate: insert into user (name, password, status, birthday) values (?, ?, ?, ?)

save 方法可以将 瞬时态 的对象变更为 持久态 对象

持久态对象

在数据库中有对应的数据,且Session 中对该对象的实例,

例如:

      // Hibernate框架加载hibernate.cfg.xml文件
        Configuration config = new Configuration().configure(); 
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();
        //开启事务
        session.beginTransaction();
        User user = new User();
        user  = session.get(User.class, 1);
        user.setName("wang");
        //事务提交
        session.getTransaction().commit();
        session.close();
        sessionFactory.close();

此时,user 为持久态对象,对持久态对象的做的修改,都会在 事务提交时 将session 中托管的对象的数据 更新到数据库,即执行一条update 语句,所以上面的代码 Hibernate会发出两条SQL语句:

Hibernate: select user0_.id as id1_0_0_, user0_.name as name2_0_0_, 
    user0_.password as password3_0_0_, user0_.status as status4_0_0_, 
    user0_.birthday as birthday5_0_0_ 
    from user user0_ where user0_.id=?
Hibernate: update user set name=?, password=?, status=?, birthday=? where id=?

Hibernate中 不允许两个相同的持久态的实例保存在session中,否则会报错,例如:

 // Hibernate框架加载hibernate.cfg.xml文件
        Configuration config = new Configuration().configure(); 
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();
        //开启事务
        session.beginTransaction();
        User u1 = session.get(User.class, 12);
        System.out.println("U1:"+u1.toString());
        User u2 = new User();
        u2.setId(12);
        u2.setStatus("A");
        u2.setBirthday(str2Date("2018-06-13 11:09:57"));
        u2.setName("xyz");
        u2.setPassword("这是密码");
        session.saveOrUpdate(u2);
        //事务提交
        session.getTransaction().commit();
        session.close();
        sessionFactory.close();

此时就会报错: A different object with the same identifier value was already associated with the session
解决方法:可以通过session的merge(Object) 方法,将两个相同的对象进行合并。


其中 saveOrUpdate 方法比较有意思:执行saveOrUpdate方法的参数对象如果是 瞬时态 或 游离态 的对象,会执行save方法,将对象变为持久态,如果是持久态对象则会执行update方法。

游离态对象

即在数据库中找不到对应的对象,在session中也找不到对应的对象,但是有唯一标示(例如user中id )

       // Hibernate框架加载hibernate.cfg.xml文件
        Configuration config = new Configuration().configure(); 
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();
        //开启事务
        session.beginTransaction();
        User user = new User();
        user  = session.get(User.class, 1);
        session.delete(user);
        user.setPassword("1");
        //事务提交
        session.getTransaction().commit();
        session.close();
        sessionFactory.close();

此时,会执行几条SQL语句呢?通过调用delete 方法,将持久态的对象user 改为游离态,此时在对user 对象的修改后,事务提交时,将不会执行update 语句,结果如下:

Hibernate: select user0_.id as id1_0_0_, user0_.name as name2_0_0_, 
    user0_.password as password3_0_0_, user0_.status as status4_0_0_, 
    user0_.birthday as birthday5_0_0_ from user user0_ where user0_.id=?
Hibernate: delete from user where id=?

参考:https://blog.csdn.net/jonnyha/article/details/80679746

 

posted on 2020-03-11 14:45  向往的生活  阅读(428)  评论(0编辑  收藏  举报

导航

页面底部