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=?