一.前言
上文Hibernate学习二:Hibernate对象状态及转换中描述了hibernate中对象的三种状态。自然的,对session中的许多方法,save(),update(),saveOrUpdate(),merge(),delete()方法,我都有了自己的想法:传什么状态的对象做为这些方法的参数,方法返回给我什么状态的对象。为了验证自己的想法,也为了方便别人,遂做此文。
二.你需要知道以下知识
如果你不愿意参考上面一篇文章,没关系,记住下面三句话:
- 临时状态对象未和任何一个session相关联,在数据库里没有对应记录,对象没有数据库标识的OID。
- 持久化状态对象和session相关联,在数据库有对应记录,对象多了一个数据库标识的OID。
- 游离状态对象不和任何一个session ,但在数据库有对应记录,对象多了一个数据库标识的OID。
三.public Serializable save(Object object) throws HibernateException;
- object是临时状态对象:直接插入记录。返回此记录对应的持久化对象。
- object是持久化状态对象:根据id先select这条记录,判断是否有更改,有则update,无则不处理。返回此记录对应的持久化对象。
- object是游离状态对象(奇葩的方法,一般没人这么搞吧):根据id先select这条记录,无论是否有更改,插入一条新记录,原记录仍然存在。返回此新记录对应的持久化对象。
public void test() {
Session session = getSession();
Transaction tr = session.beginTransaction();
//临时状态对象 执行以下sql
//Hibernate: insert into test.user (name, password) values (?, ?)
// User user = new User();
// user.setName("sa");
// user.setPassword("sa");
// session.save(user);
//持久化状态对象 执行以下sql
//Hibernate: select user0_.id as id1_0_, user0_.name as name1_0_, user0_.password as password1_0_ from test.user user0_ where user0_.id=?
//Hibernate: update test.user set name=?, password=? where id=?
// User user = (User) session.load(User.class, 1);
// user.setName("s6dd"); //如果user[1]对象以前的Name就是s6dd,不执行update语句
// session.save(user);
//游离状态对象 执行以下sql
//Hibernate: select user0_.id as id1_0_, user0_.name as name1_0_, user0_.password as password1_0_ from test.user user0_ where user0_.id=?
//Hibernate: insert into test.user (name, password) values (?, ?)
Session session2 = getSession();
User user = (User) session2.load(User.class, 1);//当通过get或load方法得到的po对象它们都处于persistent,但如果执行delete(po)时(但不能执行事务),该 po状态就处于detached,
session2.delete(user);
session2.close();
user.setName("sb");
session.save(user);
tr.commit();
session.close();
}
四.public void update(Object object) throws HibernateException;
- object是临时状态对象:直接执行update,但临时状态对象没有持久化OID,抛异常,org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1。
- object是持久化状态对象:根据id先select这条记录,判断是否有更改,有则update,无则不处理。
- object是游离状态对象:根据id先select这条记录,无论是否有更改,都执行update操作。
public void test() {
Session session = getSession();
Transaction tr = session.beginTransaction();
//临时状态对象 执行以下sql
//Hibernate: update test.user set name=?, password=? where id=?
// User user = new User();
// user.setName("sa");
// user.setPassword("sa");
// session.update(user);
//持久化状态对象 执行以下sql
//Hibernate: select user0_.id as id1_0_, user0_.name as name1_0_, user0_.password as password1_0_ from test.user user0_ where user0_.id=?
//Hibernate: update test.user set name=?, password=? where id=?
// User user = (User) session.load(User.class, 1);
// user.setName("sx122"); //如果user[1]对象以前的Name就是s6dd,不执行update语句
// session.update(user);
//游离状态对象 执行以下sql
//Hibernate: select user0_.id as id1_0_, user0_.name as name1_0_, user0_.password as password1_0_ from test.user user0_ where user0_.id=?
//Hibernate: update test.user set name=?, password=? where id=?
Session session2 = getSession();
User user = (User) session2.load(User.class, 19);//当通过get或load方法得到的po对象它们都处于persistent,但如果执行delete(po)时(但不能执行事务),该 po状态就处于detached,
session2.delete(user);
session2.close();
user.setName("2sb");
session.update(user);
tr.commit();
session.close();
}
五.public void saveOrUpdate(Object object) throws HibernateException;
- object是临时状态对象:直接执行save。此时saveOrUpdaue=save。
- object是持久化状态对象:根据id先select这条记录,判断是否有更改,有则update,无则不处理。此时saveOrUpdaue=save=update。
- object是游离状态对象:根据id先select这条记录,无论是否有更改,都执行update操作。此时saveOrUpdaue=update。
public void test() { Session session = getSession(); Transaction tr = session.beginTransaction(); //临时状态对象 执行以下sql //Hibernate: insert into test.user (name, password) values (?, ?) // User user = new User(); // user.setName("sa"); // user.setPassword("sa"); // session.saveOrUpdate(user); //持久化状态对象 执行以下sql //Hibernate: select user0_.id as id1_0_, user0_.name as name1_0_, user0_.password as password1_0_ from test.user user0_ where user0_.id=? //Hibernate: update test.user set name=?, password=? where id=? // User user = (User) session.load(User.class, 1); // user.setName("s6dd"); //如果user[1]对象以前的Name就是s6dd,不执行update语句 // session.saveOrUpdate(user); //游离状态对象 执行以下sql //Hibernate: select user0_.id as id1_0_, user0_.name as name1_0_, user0_.password as password1_0_ from test.user user0_ where user0_.id=? //Hibernate: update test.user set name=?, password=? where id=? Session session2 = getSession(); User user = (User) session2.load(User.class, 19);//当通过get或load方法得到的po对象它们都处于persistent,但如果执行delete(po)时(但不能执行事务),该 po状态就处于detached, session2.delete(user); session2.close(); // user.setName("2sb"); session.saveOrUpdate(user); tr.commit(); session.close(); }
六. public Object merge(Object object) throws HibernateException;
- object是临时状态对象:同saveOrUpdate。
- object是持久化状态对象:同saveOrUpdate。
- object是游离状态对象:根据id先select这条记录,判断是否有更改,有则update,无则不处理。
public void test() {
Session session = getSession();
Transaction tr = session.beginTransaction();
//临时状态对象 执行以下sql
//Hibernate: insert into test.user (name, password) values (?, ?)
// User user = new User();
// user.setName("sa");
// user.setPassword("sa");
// session.merge(user);
//持久化状态对象 执行以下sql
//Hibernate: select user0_.id as id1_0_, user0_.name as name1_0_, user0_.password as password1_0_ from test.user user0_ where user0_.id=?
//Hibernate: update test.user set name=?, password=? where id=?
// User user = (User) session.load(User.class, 1);
// user.setName("s6dd"); //如果user[1]对象以前的Name就是s6dd,不执行update语句
// session.merge(user);
//游离状态对象 执行以下sql
//Hibernate: select user0_.id as id1_0_, user0_.name as name1_0_, user0_.password as password1_0_ from test.user user0_ where user0_.id=?
//Hibernate: update test.user set name=?, password=? where id=?
Session session2 = getSession();
User user = (User) session2.load(User.class, 19);//当通过get或load方法得到的po对象它们都处于persistent,但如果执行delete(po)时(但不能执行事务),该 po状态就处于detached,
session2.delete(user);
session2.close();
user.setName("2sb");session.merge(user);
tr.commit();
session.close();
}
七.public void delete(Object object) throws HibernateException;
- object是临时状态对象:居然不执行delete语句,难道是自动优化,session发现这个临时对象没有OID,忽略此次delete。
- object是持久化状态对象:直接delete记录,并清空session中对应缓存。
- object是游离状态对象:直接delete。
public void test() {
Session session = getSession();
Transaction tr = session.beginTransaction();
//临时状态对象 不执行sql
// User user = new User();
// user.setName("sa");
// user.setPassword("sa");
// session.delete(user);
//持久化状态对象 执行以下sql
//Hibernate: select user0_.id as id1_0_, user0_.name as name1_0_, user0_.password as password1_0_ from test.user user0_ where user0_.id=?
//Hibernate: delete from test.user where id=?
// User user = (User) session.load(User.class, 19);
// session.delete(user);
//游离状态对象 执行以下sql
//Hibernate: select user0_.id as id1_0_, user0_.name as name1_0_, user0_.password as password1_0_ from test.user user0_ where user0_.id=?
//Hibernate: delete from test.user where id=?
Session session2 = getSession();
User user = (User) session2.load(User.class, 20);//当通过get或load方法得到的po对象它们都处于persistent,但如果执行delete(po)时(但不能执行事务),该 po状态就处于detached,
session2.delete(user);
session2.close();
session.delete(user);
tr.commit();
session.close();
}
七.saveOrUpdate()和merge()
- saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对
象会直接从session缓存中取。 - merge后的对象不会纳入session的管理,再次查询该对象还是会从数据库中取。