论坛首页 Java企业应用论坛

saveorUpdate与unsaved-value,save,update,delete总结

浏览 13351 次
该帖已经被评为良好帖
作者 正文
   发表时间:2006-10-13  
这些操作对经常使用hibernate的同学已经很熟悉了,我也经常用但一些细节并不了解,
最近遇到问题才开始有看了一下。

在读完robbin的这两个精华贴的时候,感觉清晰了很多,确实好文章。
http://www.iteye.com/topic/2712
http://www.iteye.com/topic/1604?page=1
还有这个精华贴
http://www.iteye.com/topic/7484
也很不错。

里面总结的很好了,我结合以上三个帖子、自己的试验(版本hibernate-3.0.5)和Hibernate文档也总结了一点,加深理解。希望对刚开始学Hibernate的同学有所帮助

一、saveorUpdate与unsaved-value
到底是sava还是update
Hibernate需要判断被操作的对象究竟是一个已经持久化过的持久对象还是临时对象。
1).主键Hibernate的id generator产生
<id name="id" type="java.lang.Long">
     <column name="ID" precision="22" scale="0" />
      <generator class="increment" />
</id>

Project project = new Project();
project.setId(XXX);
this.projectDao.saveOrUpdate(project);

1、默认unsaved-value="null"
主键是对象类型,hebernate判断project的主键是否位null,来判断project是否已被持久化
是的话,对project对象发送save(project),
若自己设置了主键则直接生成update的sql,发送update(project),即便数据库里没有那条记录。
主键是基本类型如int/long/double/
自己设置unsaved-null="0"。
所以这样的话save和update操作肯定不会报错。

2、unsaved-value="none",
由于不论主键属性为任何值,都不可能为none,因此Hibernate总是对project对象发送update(project)

3、unsaved-value="any"
由于不论主键属性为任何值,都肯定为any,因此Hibernate总是对project对象发送save(project),hibernate生成主键。

Hibernate文档中写到
saveOrUpdate()完成了如下工作:
如果对象已经在这个session中持久化过了,什么都不用做
如果对象没有标识值,调用save()来保存它
如果对象的标识值与unsaved-value中的条件匹配,调用save()来保存它
如果对象使用了版本(version或timestamp),那么除非设置unsaved-value="undefined",版本检查会发生在标识符检查之前.
如果这个session中有另外一个对象具有同样的标识符,抛出一个异常

2).主键由自己来赋值
<id name="id" type="java.lang.Long">
       <column name="ID" precision="22" scale="0" />
       <generator class="assigned" />
</id>

Project project = new Project();
project.setId(XXX);
this.projectDao.saveOrUpdate(project);

1、默认unsaved-value="null"
这时有所不同,hibernate会根据主键产生一个select,来判断此对象是否已被持久化
已被持久化则update,未被持久化则save。
2、unsaved-value="none",update对象,同上

3、unsaved-value="any" ,save对象,
如果自己自己设置的ID在数据库中已存在,则报错。

二、save与update操作
显式的使用session.save()或者session.update()操作一个对象的时候,实际上是用不到unsaved-value的
在同一Session,save没什么可说得
update对象时, 最直接的更改一个对象的方法就是load()它,保持Session打开,然后直接修改即可:
Session s =…
Project p = (Project) sess.load(Project.class, id) );
p.setName(“test”);
s.flush();
不用调用s.update(p);hibernate能察觉到它的变化,会自动更新。当然显示调用的话也不会错

Hibernate文档中写到
update()方法在下列情形下使用:
程序在前面的session中装载了对象
对象被传递到UI(界面)层
对该对象进行了一些修改
对象被传递回业务层
应用程序在第二个session中调用update()保存修改

三、delete操作
删除时直接自己构造一个project即可删除
this.projectDao.delete(preojct);

以前删除我是这样写的
public void deleteProject(String id) {
Project project = (Project) this.projectDao.get(Project.class, id);
if (project != null) {
this.projectDao.delete(project);
}
即这样也是可以的
Project project = new Project();
project.setId(id);
this.projectDao.delete(project).

如果有级联关系,需要把级联的子类也构造出来add进去,同样可以删除。

好了,罗嗦的够多了。
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics