欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Hibernate save() saveorupdate()的用法第1/2页

程序员文章站 2022-03-25 20:21:35
一个po有三种状态: 1、未被持久化的vo 此时就是一个内存对象vo,由jvm管理生命周期 2、已被持久化的po,并且在session生命周期内 此时映射数据库数据,由数据...

一个po有三种状态:
1、未被持久化的vo
此时就是一个内存对象vo,由jvm管理生命周期
2、已被持久化的po,并且在session生命周期内
此时映射数据库数据,由数据库管理生命周期
3、曾被持久化过,但现在和session已经detached了,以vo的身份在运行
这种和session已经detached的po还能够进入另一个session,继续进行po状态管理,此时它就成为po的第二种状态了。这种po实际上是跨了session进行了状态维护的。
在传统的jdo1.x中,po只有前面两种状态,一个po一旦脱离pm,就丧失了状态了,不再和数据库数据关联,成为一个纯粹的内存vo,它即使进入一个新的pm,也不能恢复它的状态了。
hibernate强的地方就在于,一个po脱离session之后,还能保持状态,再进入一个新的session之后,就恢复状态管理的能力,但此时状态管理需要使用session.update或者session.saveorupdate,这就是hibernate reference中提到的“requires a slightly different programming model ”
现在正式进入本话题:
简单的来说,update和saveorupdate是用来对跨session的po进行状态管理的。
假设你的po不需要跨session的话,那么就不需要用到,例如你打开一个session,对po进行操作,然后关闭,之后这个po你也不会再用到了,那么就不需要用update。
因此,我们来看看上例:
java代码
foo foo=sess.load(foo.class,id);;
foo.setxxx(xxx);;
sess.flush();;
sess.commit();;

foo foo=sess.load(foo.class,id);;
foo.setxxx(xxx);;
sess.flush();;
sess.commit();;
foo foo=sess.load(foo.class,id);;
foo.setxxx(xxx);;
sess.flush();;
sess.commit();;
po对象foo的操作都在一个session生命周期内完成,因此不需要显式的进行sess.update(foo)这样的操作。hibernate会自动监测到foo对象已经被修改过,因此就向数据库发送一个update的sql。当然如果你非要加上sess.update(foo)也不会错,只不过这样做没有任何必要。
而跨session的意思就是说这个po对象在session关闭之后,你还把它当做一个vo来用,后来你在session外面又修改了它的属性,然后你又想打开一个session,把vo的属性修改保存到数据库里面,那么你就需要用update了。
java代码
// in the first session
cat cat = (cat); firstsession.load(cat.class, catid);;
cat potentialmate = new cat();;
firstsession.save(potentialmate);;
// in a higher tier of the application
cat.setmate(potentialmate);;
// later, in a new session
secondsession.update(cat);; // update cat
secondsession.update(mate);; // update mate

// in the first session
cat cat = (cat); firstsession.load(cat.class, catid);;
cat potentialmate = new cat();;
firstsession.save(potentialmate);;
// in a higher tier of the application
cat.setmate(potentialmate);;
// later, in a new session
secondsession.update(cat);; // update cat
secondsession.update(mate);; // update mate
// in the first session
cat cat = (cat); firstsession.load(cat.class, catid);;
cat potentialmate = new cat();;
firstsession.save(potentialmate);;
// in a higher tier of the application
cat.setmate(potentialmate);;
// later, in a new session
secondsession.update(cat);; // update cat
secondsession.update(mate);; // update mate
cat和mate对象是在第一个session中取得的,在第一个session关闭之后,他们就成了po的第三种状态,和session已经detached的po,此时他们的状态信息仍然被保留下来了。当他们进入第二个session之后,立刻就可以进行状态的更新。但是由于对cat的修改操作:cat.setmate(potentialmate); 是在session外面进行的,hibernate不可能知道cat对象已经被改过了,第二个session并不知道这种修改,因此一定要显式的调用secondsession.update(cat); 通知hibernate,cat对象已经修改了,你必须发送update的sql了。
所以update的作用就在于此,它只会被用于当一个po对象跨session进行状态同步的时候才需要写。而一个po对象当它不需要跨session进行状态管理的时候,是不需要写update的。
再谈谈saveorupdate的用场:
saveorupdate和update的区别就在于在跨session的po状态管理中,hibernate对po采取何种策略。
例如当你写一个daoimpl的时候,让cat对象增加一个mate,如下定义:
java代码
public void addmate(cat cat, mate mate); {
session session = ...;
transacton tx = ...;
session.update(cat);;
cat.addmate(mate);;
tx.commit();;
session.close();;
};

public void addmate(cat cat, mate mate); {
session session = ...;
transacton tx = ...;
session.update(cat);;
cat.addmate(mate);;
tx.commit();;
session.close();;
};
public void addmate(cat cat, mate mate); {
session session = ...;
transacton tx = ...;
session.update(cat);;
cat.addmate(mate);;
tx.commit();;
session.close();;
};
显然你是需要把hibernate的操作封装在dao里面的,让业务层的程序员和web层的程序员不需要了解hibernate,直接对dao进行调用。

1