以下代码运行在Hibernate 3.1.3下面,下面的代码展示了不同情况或状态的对象在作更新时可能发生的结果:
session = HibernateUtil.currentSession();
Example exp2 = null ;
Example exp3 = null ;
Example exp1 =null ;
exp1 = (Example)session.load(Example.class,"1 ");
exp1.setExampleCode("exp99");
HibernateUtil.closeSession();
exp1.setExampleCode("1111");
exp1.setCreateDate(DateUtil.getCurrentTimestamp());
exp2 = new Example();
exp2.setExampleID("2");
exp2.setExampleCode("2222");
exp2.setCreateDate(DateUtil.getCurrentTimestamp());
exp3 = new Example();
exp3.setExampleID("4");
exp3.setExampleCode("4444");
exp3.setCreateDate(DateUtil.getCurrentTimestamp());
session = HibernateUtil.currentSession();
tx = session.beginTransaction();
session.update(exp1);
session.update(exp2);
session.update(exp3);
tx.commit();
HibernateUtil.closeSession();
这里面有三种情况:
exp1的情况是:与数据库同步过或是从数据库读取过后,session 关闭,而后又对exp1进行了修改,再从新的session 中将修改与数据库同步。
exp2的情况是:本身未与数据库同步过,但是它所代表的数据在数据库中存在
exp3的情况是:本身未与数据库同步过,但是它所代表的数据在数据库中不存在
现在对红色标出的代码部分变化时对执行结果的影响进行分析:
如果是update操作, 这三种情况的结果如下:
case1:日志中产生一条update语句,并且更新了数据库中的数据
case2:日志中产生一条update语句,并且更新了数据库中的数据
case3:日志中产生一条update语句,但对数据库没有影响,因为根本不存在那个id对应的数据
如果是saveOrUpdate操作,情况则繁琐一些:
(1)如果指定id 的generator-class="assigned",
(1.1)如果指定Id 的 unsaved-value="null"
则生成三条update语句
(1.2)如果没有指定Id 的 unsaved-value
则生成三条insert语句。
(1.3)如果指定Id 的 unsaved-value="undefined"
case1:日志中产生一条update语句,并且更新了数据库中的数据
case2:日志中产生一条update语句,并且更新了数据库中的数据
case3:日志中产生一条insert语句,数据库中插入了一条数据
但由于在这种条件下 ,是强制Hibernate查询数据库以判断对象到底是暂态(transient )还是只是脱管(detached)的,个人认为这样可能会导致性能不高,所以对于事前已经知道是transient状态的对象,直接对其进行save操作就行了。
(2)其他的generator-class还没有试过
结论:Update:是对暂态(transient )或是只是脱管(detached)的更新操作,对于暂态对象的更新操作通常不产生效果,对于脱 管对象是做了同步的操作,即数据库的数据发生变化并且对象状态也成为托管对象
SaveOrUpdate : 也是对暂态(transient )或是只是脱管(detached)的进行操作,至于是插入还是更新,则要根据id 中指定的一些具体条件来分析。但是个人认为在明显只会发生插入操作的情况还是尽量避免用saveOrUpdate而直接用save即可。