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

一个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/2页 12下一页阅读全文

(0)

相关推荐

  • hibernate更新数据方法小结

    复制代码 代码如下: Usertable user=null; Session session=HibernateSessionFactory.getSession(); String sql="from Usertable as user where user.username=?"; Query q=session.createQuery(sql); q.setString(0,username); List l=q.list(); Iterator ite=l.iterator(

  • 解决Hibernate4执行save()或update()无效问题的方法

    最近在写网上商城项目时,遇到一个问题:Hibernate在执行save()或者update()方法后,并没有任何效果,数据库中没有任何改动,而且控制台也没有报任何错,这让我很无语-- 我在网上查了下,有的人说是主键的自增长问题,有的人说是没有开启事务,所以无法写入或更新数据库,我详细看了他们的分析,说的都有道理,但是这些解决方法对我都不管用,因为我的主键是没有问题的,事务是由Spring管理的,在其他save操作都可以,都没有问题. 既然客观上都没有问题,于是我把焦点放在了具体要save或upd

  • java Hibernate save()与persist()区别

    Hibernate 之所以提供与save()功能几乎完全类似的persist()方法,一方面是为了照顾JPA的用法习惯.另一方面,save()和 persist()方法还有一个区别:使用 save() 方法保存持久化对象时,该方法返回该持久化对象的标识属性值(即对应记录的主键值):但使用 persist() 方法来保存持久化对象时,该方法没有任何返回值.因为 save() 方法需要立即返回持久化对象的标识属性,所以程序执行 save() 会立即将持久化对象对应的数据插入数据库:而 persist

  • jsp hibernate的分页代码第1/3页

    可见使用Hibernate,在进行查询分页的操作上,是具有非常大的灵活性,Hibernate会首先尝试用特定数据库的分页sql,如果没用,再尝试Scrollable,如果不行,最后采用rset.next()移动的办法. (一)pager类 * @(#)Pager.java 2005-5-3 * * Copyright (c) 2005, Jeffrey Hsu */ package com.jeffrey.messagelove; /** * Pager holds the page info.

  • struts2+spring+hibernate分页代码[比较多]第1/7页

    dao层接口: Java代码 复制代码 代码如下: package com.last999.im.news.dao; import java.util.*; import com.last999.im.news.entity.KindEntity; import com.last999.im.news.web.PageTool; public interface KindEntityDao{ public KindEntity get(String uuid); public void save

  • Hibernate 查询方式总结

    1. get() and load() Java代码 session.get(Clazz, id); session.load(Clazz, id); session.get(Clazz, id); session.load(Clazz, id); 说明: load()与get()的区别 请注意如果没有匹配的数据库记录,load()方法可能抛出无法恢复的异常(unrecoverable exception). 如果类的映射使用了代理(proxy),load()方法会返回一个未初始化的代理,直到你

  • 解析使用jdbc,hibernate处理clob/blob字段的详解

    (1)不同数据库中对应clob,blob的类型:mysql中 : clob对应text  blob对应blobdb2/oracle中 clob对应clob blob对应blob (2)domain中对应类型:clob 对应 String   blob 对应 byte[]clob 对庆 java.sql.Clob blob 对应 java.sql.Blob (3)hibernate配置文件中对应类型:clob > clob   blob > binay 也可以直接使用数据库提供类型,例如:ora

  • SSH整合中 hibernate托管给Spring得到SessionFactory

    <prop key="hibernate.current_session_context_class">thread</prop> 然后 Resource resource=new ClassPathResource("/WEB-INF/applicationContext.xml"); BeanFactory factory=new XmlBeanFactory(resource); SessionFactory sessionFactor

  • hibernate中的增删改查实现代码

    第一个我们首先看看增,增在SQL里面就是insert,也就是插入,在hibernate中,我们只需要,操纵一个对象进行sava,然后再commit事务,就能实现插入功能,下面给大家具体看看代码,持久类我就不再写了,里面也就是与数据库中的字段要一一对应的东西,要有set,get方法,我直接就写的怎么调用save方法. //导入所需的包 import org.hibernate.HibernateException; import org.hibernate.Session; import org.

  • 解决hibernate+mysql写入数据库乱码

    hibernate.cfg.xml加上属性. <property name="connection.useUnicode">true</property> <property name="connection.characterEncoding">UTF-8</property> mysql 的驱动用3.0.15以上版本的, 加个Filter, 使用UTF-8字符集就可以了, 若使用Spring则写在spring中的s

随机推荐