zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    洛谷 P1226 【模板】快速幂||取余运算 题解
    洛谷 P2678 跳石头 题解
    洛谷 P2615 神奇的幻方 题解
    洛谷 P1083 借教室 题解
    洛谷 P1076 寻宝 题解
    洛谷 UVA10298 Power Strings 题解
    洛谷 P3375 【模板】KMP字符串匹配 题解
    Kafka Shell基本命令
    Mybatis与Hibernate的详细对比
    MyBatis简介
  • 原文地址:https://www.cnblogs.com/jichuang/p/12462337.html
Copyright © 2011-2022 走看看