POJO 与PO的概念

POJO = pure old java object or plain ordinary java object or what ever.

PO = persisent object 持久对象

POJO--Plain Ordinary Java Object(无格式普通Java对象)
BO--Business Object(商业对象)
VO--Value Object(值对象)
PO--Persistence Object(持久对象)

BO .主要实现主要的业务逻辑,所以BO对象往往都是大粒度的.因为每个请求一般都以业务为主,因此推荐将Hibernate 的session放到BO 中进行初始化和关闭.
VO 主要作为一些程序中使用的值的对应对象,因此一般只进行简单的数据存储.
POJO 也存在类似的功能,同时.可以作为Hibernate与数据库中的表对应的持久对象..因此值得关注.



就是说在一些Object/Relation Mapping工具中,能够做到维护数据库表记录的persisent object完全是一个符合Java Bean规范的纯Java对象,没有增加别的属性和方法。全都是这样子的:


java代码: 

public class User {
  private long id;
  private String name;
  public void setId(long id) {
this.id = id;
} 
public void setName(String name) {
this.name=name;
}
public long getId() {
return id;
} 
public String getName() {
return name;
}
} 



---------------------------------------------------------------------------
首先要区别持久对象和POJO。

持久对象实际上必须对应数据库中的entity,所以和POJO有所区别。比如说POJO是由new创建,由GC回收。但是持久对象是insert数据库创建,由数据库delete删除的。基本上持久对象生命周期和数据库密切相关。另外持久对象往往只能存在一个数据库Connection之中,Connnection关闭以后,持久对象就不存在了,而POJO只要不被GC回收,总是存在的。

由于存在诸多差别,因此持久对象PO(Persistent Object)在代码上肯定和POJO不同,起码PO相对于POJO会增加一些用来管理数据库entity状态的属性和方法。而ORM追求的目标就是要PO在使用上尽量和POJO一致,对于程序员来说,他们可以把PO当做POJO来用,而感觉不到PO的存在。

JDO的实现方法是这样的:
1、编写POJO
2、编译POJO
3、使用JDO的一个专门工具,叫做Enhancer,一般是一个命令行程序,手工运行,或者在ant脚本里面运行,对POJO的class文件处理一下,把POJO替换成同名的PO。
4、在运行期运行的实际上是PO,而不是POJO。

该方法有点类似于JSP,JSP也是在编译期被转换成Servlet来运行的,在运行期实际上运行的是Servlet,而不是JSP。

Hibernate的实现方法比较先进:
1、编写POJO
2、编译POJO
3、直接运行,在运行期,由Hibernate的CGLIB动态把POJO转换为PO。

由此可以看出Hibernate是在运行期把POJO的字节码转换为PO的,而JDO是在编译期转换的。一般认为JDO的方式效率会稍高,毕竟是编译期转换嘛。但是Hibernate的作者Gavin King说CGLIB的效率非常之高,运行期的PO的字节码生成速度非常之快,效率损失几乎可以忽略不计。

实际上运行期生成PO的好处非常大,这样对于程序员来说,是无法接触到PO的,PO对他们来说完全透明。可以更加自由的以POJO的概念操纵PO。另外由于是运行期生成PO,所以可以支持增量编译,增量调试。而JDO则无法做到这一点。实际上已经有很多人在抱怨JDO的编译期Enhancer问题了,而据说JBossDO将采用运行期生成PO字节码,而不采用编译期生成PO字节码。

另外一个相关的问题是,不同的JDO产品的Enhancer生成的PO字节码可能会有所不同,可能会影响在JDO产品之间的可移植性,这一点有点类似EJB的可移植性难题。

-----------------------------------------------------------------------------------
由这个问题另外引出一个JDO的缺陷。

由于JDO的PO状态管理方式,所以当你在程序里面get/set的时候,实际上不是从PO的实例中取values,而是从JDO StateManager中取出来,所以一旦PM关闭,PO就不能进行存取了。

在JDO中,也可以通过一些办法使得PO可以在PM外面使用,比如说定义PO是transient的,但是该PO在PM关闭后就没有PO identity了。无法进行跨PM的状态管理。

而Hibernate是从PO实例中取values的,所以即使Session关闭,也一样可以get/set,可以进行跨Session的状态管理。

在分多层的应用中,由于持久层和业务层和web层都是分开的,此时Hibernate的PO完全可以当做一个POJO来用,也就是当做一个VO,在各层间自由传递,而不用去管Session是开还是关。如果你把这个POJO序列化的话,甚至可以用在分布式环境中。(不适合lazy loading的情况)

但是JDO的PO在PM关闭后就不能再用了,所以必须在PM关闭前把PO拷贝一份VO,把VO传递给业务层和web层使用。在非分布式环境中,也可以使用ThreadLocal模式确保PM始终是打开状态,来避免每次必须进行PO到VO的拷贝操作。但是不管怎么说,这总是权宜之计,不如Hibernate的功能强。
  
### 概念 - **VO(Value Object)**:用作表示层,是POJO在表示层的体现形式,用于向视图层传输数据,通常用于前端展示数据的封装 [^1][^3]。 - **DTO(Data Transfer Object)**:是POJO在传输过程中的表现形式,主要用于不同层之间或者不同系统之间的数据传输,将数据封装成一个对象进行传递,减少数据传输的次数和数据量 [^1][^3]。 - **PO(Persistent Object)**:是POJO持久化之后的对象,在运行期,由Hibernate中的cglib动态把POJO转换PO,相对于POJO会增加一些用来管理数据库entity状态的属性和方法,对于程序员来说完全透明,支持增量编译和调试 [^1]。 - **POJO(Plain Ordinary Java Object)**:简单的Java对象,实际就是普通JavaBeans,通指没有使用Entity Beans的普通java对象,可以作为支持业务逻辑的协助类,其作用是方便程序员使用数据库中的数据表,可方便调用其get、set方法 [^3][^4][^5]。 - **Domain**:在国外很多项目中经常用到,字面意思是域,通常代表业务领域的概念,包含业务规则和业务逻辑,是业务对象的抽象表示 [^4]。 - **Entity**:接近原始数据,是专用于EF(可能指Entity Framework)的对数据库表的操作,数据库中的表相对应,用于数据的持久化操作 [^4]。 ### 区别 - **VO和DTO**:VO主要用于展示层,关注的是数据的展示形式;DTO主要用于数据传输,关注的是数据的传递效率和完整性。 - **POPOJO**:POPOJO持久化后的结果,POJO是普通的Java对象,POPOJO多了一些管理数据库状态的属性和方法。 - **Domain和其他对象**:Domain更侧重于业务领域的抽象,包含业务规则和逻辑,而其他对象更多地关注数据的存储、传输和展示。 - **Entity和PO**:Entity数据库表直接对应,是对数据库表的操作;POPOJO持久化后的对象,更强调对象在持久化过程中的状态管理。 ### 使用场景 - **VO**:在Web应用的表示层,如JSP页面、前端界面等,将数据展示给用户时使用,例如将数据库中的用户信息封装成VO对象传递给前端页面显示 [^1][^3]。 - **DTO**:在不同层之间(如Controller层和Service层、Service层和DAO层)或者不同系统之间进行数据传输时使用,例如在微服务架构中,不同服务之间通过DTO进行数据交互 [^1][^3]。 - **PO**:在进行数据库持久化操作时使用,例如使用Hibernate、MyBatis等框架进行数据的增删改查操作时,将PO对象数据库表进行映射 [^1]。 - **POJO**:在业务逻辑处理中作为辅助类使用,例如在Service层中,使用POJO对象来封装业务逻辑处理所需的数据 [^3][^4][^5]。 - **Domain**:在业务逻辑层中使用,用于封装业务规则和业务逻辑,例如在订单业务中,使用Domain对象来处理订单的创建、支付、取消等业务操作 [^4]。 - **Entity**:在数据持久化层中使用,数据库表进行映射,通过Entity对象进行数据库的增删改查操作,例如使用Entity Framework进行数据库操作时,定义Entity类来表示数据库表 [^4]。 ### 代码示例 以下是一个简单的Java代码示例,展示了VO、DTO、POPOJO的使用: ```java // POJO类 class UserPOJO { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } // PO类 class UserPO extends UserPOJO { // 增加管理数据库状态的属性和方法 private boolean isDeleted; public boolean isDeleted() { return isDeleted; } public void setDeleted(boolean deleted) { isDeleted = deleted; } } // DTO类 class UserDTO { private String name; private int age; public UserDTO(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } // VO类 class UserVO { private String name; private int age; public UserVO(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值