`
fudehai001
  • 浏览: 497304 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

PO和VO的区别

阅读更多
先来点概念:

在Hibernate中,最核心的概念就是对PO的状态管理。一个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代码

   1. Foo foo=sess.load(Foo.class,id);;  
   2. foo.setXXX(xxx);;  
   3. sess.flush();; 
   4. 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代码

   1. // in the first session  
   2. Cat cat = (Cat); firstSession.load(Cat.class, catId);;  
   3. Cat potentialMate = new Cat();;  
   4. firstSession.save(potentialMate);;  
   5.  
   6. // in a higher tier of the application  
   7. cat.setMate(potentialMate);;  
   8.  
   9. // later, in a new session  
  10. secondSession.update(cat);;  // update cat  
  11. 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代码

   1. public void addMate(Cat cat, Mate mate); { 
   2.     Session session = ...; 
   3.     Transacton tx = ...; 
   4.     session.update(cat);; 
   5.     cat.addMate(mate);; 
   6.     tx.commit();; 
   7.     session.close();; 
   8. }; 

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进行调用。

此时问题就来了:上面的代码运行正确有一个必要的前提,那就是方法调用参数cat对象必须是一个已经被持久化过的PO,也就是来说,它应该首先从数据库查询出来,然后才能这样用。但是业务层的程序员显然不知道这种内部的玄妙,如果他的业务是现在增加一个cat,然后再增加它的mate,他显然会这样调用,new一个cat对象出来,然后就addMate:

Java代码

   1. Cat cat = new Cat();; 
   2. cat.setXXX();; 
   3. daoimpl.addMate(cat,mate);; 

Cat cat = new Cat();;
cat.setXXX();;
daoimpl.addMate(cat,mate);;



但是请注意看,这个cat对象只是一个VO,它没有被持久化过,它还不是PO,它没有资格调用addMate方法,因此调用addMate方法不会真正往数据库里面发送update的sql,这个cat对象必须先被save到数据库,在真正成为一个PO之后,才具备addMate的资格。

你必须这样来操作:

Java代码

   1. Cat cat = new Cat();; 
   2. cat.setXXX();; 
   3. daoimpl.addCat(cat);; 
   4. daoimpl.addMate(cat, mate);; 

Cat cat = new Cat();;
cat.setXXX();;
daoimpl.addCat(cat);;
daoimpl.addMate(cat, mate);;



先持久化cat,然后才能对cat进行其他的持久化操作。因此要求业务层的程序员必须清楚cat对象处于何种状态,到底是第一种,还是第三种。如果是第一种,就要先save,再addMate;如果是第三种,就直接addMate。

但是最致命的是,如果整个软件分层很多,业务层的程序员他拿到这个cat对象也可能是上层Web应用层传递过来的cat,他自己也不知道这个cat究竟是VO,没有被持久化过,还是已经被持久化过,那么他根本就没有办法写程序了。

所以这样的DAOImpl显然是有问题的,它会对业务层的程序员造成很多编程上的陷阱,业务层的程序员必须深刻的了解他调用的每个DAO对PO对象进行了何种状态管理,必须深刻的了解他的PO对象在任何时候处于什么确切的状态,才能保证编程的正确性,显然这是做不到的,但是有了 saveOrUpdate,这些问题就迎刃而解了。

现在你需要修改addMate方法:

Java代码

   1. public void addMate(Cat cat, Mate mate); { 
   2.     Session session = ...; 
   3.     Transacton tx = ...; 
   4.     session.saveOrUpdate(cat);; 
   5.     cat.addMate(mate);; 
   6.     tx.commit();; 
   7.     session.close();; 
   8. }; 

public void addMate(Cat cat, Mate mate); {
    Session session = ...;
    Transacton tx = ...;
    session.saveOrUpdate(cat);;
    cat.addMate(mate);;
    tx.commit();;
    session.close();;
};



如上,如果业务层的程序员传进来的是一个已经持久化过的PO对象,那么Hibernate会更新cat对象(假设业务层的程序员在Session外面修改过cat的属性),如果传进来的是一个新new出来的对象,那么向数据库save这个PO对象。

BTW: Hibernate此时究竟采取更新cat对象,还是save cat对象,取决于unsave-value的设定。

这样,业务层的程序员就不必再操心PO的状态问题了,对于他们来说,不管cat是new出来的对象,只是一个VO也好;还是从数据库查询出来的的PO对象也好,全部都是直接addMate就OK了:

Java代码

   1. daoimple.addMate(cat, mate);; 

daoimple.addMate(cat, mate);;



这便是saveOrUpdate的作用。
分享到:
评论

相关推荐

    po与vo区别.doc

    总结来说,PO和VO的主要区别在于其设计目标和应用场景: - PO主要面向数据持久化,与数据库表结构紧密相关,而VO则侧重于数据传输,常用于服务和视图间的交互。 - PO可能包含数据库映射信息,而VO则不涉及数据库...

    关于VO、PO的理解——java的(PO,VO,TO,BO,DAO,POJO)解释

    PO 和 VO 之间的关系是相互独立的,一个 VO 可以只是 PO 的部分,也可以是多个 PO 构成,同样也可以等同于一个 PO。正因为这样,PO 独立出来,数据持久层也就独立出来了,它不会受到任何业务的干涉。 TO(Transfer ...

    Java的(PO,VO,TO,BO,DAO,POJO)解释

    VO在Web上传递中也可以和DTO(数据传输对象)混淆,但它们之间有一些细微的区别。 TO(Transfer Object)数据传输对象 TO是Java中的数据传输对象,在应用程序不同关系之间传输的对象。TO通常用于数据的传输和交换,...

    Oracle 自动生成POVO工具

    总之,Oracle POVO工具是Java开发中的得力助手,它通过自动化的方式帮助开发者快速生成符合规范的POJO和VO类,使得团队能更专注于业务逻辑的实现,而非基础架构的搭建。对于大型Oracle数据库项目,这样的工具无疑是...

    自身关联的添加、检索及PO到VO得封装、转换

    在IT行业中,自身关联是一种常见的数据库设计技巧,用于表示一个实体可以与其...在实际开发中,这种设计允许构建复杂的数据结构,如树形菜单或权限系统,同时PO到VO的转换是数据层和业务层交互中常见的数据处理方式。

    po vo dto bo to

    ### Java中的PO、VO、TO、BO、...PO、VO、TO、BO、DAO与POJO各自在系统架构的不同层次中扮演着不同的角色,相互之间既有联系又有区别。理解这些对象的概念及其应用场景,有助于我们在开发过程中做出更合适的设计选择。

    Java的几种对象(PO-VO-DAO-BO-POJO)解释

    2. **VO与PO的区别**: - **VO**是值对象,更侧重于业务逻辑层面;而**PO**是有状态的,每个属性代表其当前的状态。 - **VO**的属性根据当前业务逻辑的不同而不同,与业务逻辑紧密相关;而**PO**的属性与数据库表...

    Java中 PO VO BO DTO DAO 和 POJO 关系图

    Java中 PO VO BO DTO DAO 和 POJO 关系图

    vopo转换工具类及所需jar

    总的来说,"vopo转换工具类及所需jar"是一个简化vopo数据格式转换的解决方案,它包含了一个数据验证助手和一个主要的转换器类,以及一系列的外部依赖库。通过这个工具,开发者可以在处理vopo数据时提高效率,减少...

    java中PO、VO、BO、POJO、DAO、DTO、TO、QO、Bean、conn的理解

    它们之间的关系是:BO 封装业务逻辑,调用 DAO 方法,结合 PO 和 VO 进行业务操作。DAO 中包含了各种数据库的操作方法,通过它的方法,结合 PO 对数据库进行相关的操作。DTO 和 TO 是用于传输数据的对象,可以减少...

    java(PO,VO,BO,DAO,POJO)Explained Collection

    Java开发中,PO(Persistant Object)、VO(Value Object)、BO(Business Object)、DAO(Data Access Object)和POJO(Plain Old Java Object)是常见的五个概念,它们在软件设计和开发中扮演着不同的角色。...

    java术语(PO/POJO/VO/BO/DAO/DTO)

    本文将详细解析"PO/POJO/VO/BO/DAO/DTO"这六个概念,并探讨它们在实际项目开发中的作用和应用场景。 1. PO(Persistent Object,持久化对象) PO是指与数据库表结构一一对应的Java对象,它通常包含了数据库表中的...

    JAVA中的POJO、VO、PO、DO、DTO都是什么?有什么区别?

    以下是关于POJO、VO、PO、DO、DTO的详细解释及其区别。 1. POJO(Plain Old Java Object):POJO是一个通用术语,指没有特定框架限制的简单Java对象。它通常包含了业务逻辑和数据属性,不包含任何特定框架的注解或...

    java的几种对象(PO_VO_DAO_BO_POJO)解释

    本文将深入探讨五种常见的Java对象类型:持久化对象(Persistent Object,简称PO)、值对象(Value Object,简称VO)、数据访问对象(Data Access Object,简称DAO)、业务对象(Business Object,简称BO)和平凡的...

    bo,vo,po的区别

    在IT行业中,尤其是在Java开发领域,我们经常遇到“VO”、“BO”和“PO”这样的术语,它们分别代表了Value Object、Business Object和Persistent Object。理解这三个概念对于编写清晰、可维护的代码至关重要。 首先...

    VO / DTO / BO / ORM DAO entity DO PO/ POJO(分层领域模型规约)整理

    本文将详细介绍VO (View Object)、DTO (Data Transfer Object)、BO (Business Object)、ORM (Object Relational Mapping)、DAO (Data Access Object)、Entity (实体)、DO (Data Object)、PO (Persistent Object)、...

    vo bo po dto dao区别

    本人以前搞不懂这些o的区别,特意查找资料总结了一下,希望也可以帮到其他人

    Java Web开发 之VO、PO、DTO等收集

    J2EE开发人员必须知道 Java Web开发中VO、PO、DTO、POJO代表含义。

    J2EE基础知识之DTO,VO,PO,DO等定义

    J2EE基础知识之DTO,VO,PO,DO等定义J2EE基础知识之DTO,VO,PO,DO等定义J2EE基础知识之DTO,VO,PO,DO等定义

Global site tag (gtag.js) - Google Analytics