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