浏览 2087 次
锁定老帖子 主题:hibernate-po与vo的比较
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-03-31
VO即 Value Object PO和VO是Hibernate中两个比较关键的概念。 首先,何谓VO,很简单,VO就是一个简单的值对象。 如: TUser user = new TUser(); user.setName("Emma");这里的user就是一个VO。VO只是简单携带了对象的一些属性信息。 何谓PO? 即纳入Hibernate管理框架中的VO。 看下面两个例子: 例一: TUser user = new TUser(); TUser anotherUser = new TUser(); user.setName("Emma"); anotherUser.setName("Kevin"); //此时user和anotherUser都是VO Transaction tx = session.beginTransaction(); session.save(user); //此时的user已经经过Hibernate的处理,成为一个PO //而anotherUser仍然是个VO tx.commit(); //事务提交之后,库表中已经插入一条用户”Emma”的记录 //对于anotherUser则无任何操作 Transaction tx = session.beginTransaction(); user.setName("Emma_1"); //PO anotherUser.setName("Kevin_1");//VO tx.commit(); //事务提交之后,PO的状态被固化到数据库中 //也就是说数据库中“Emma”的用户记录已经被更新为“Emma_1” //此时anotherUser仍然是个普通Java对象,它的属性更改不会 //对数据库产生任何影响 例二:通过Hibernate返回的对象也是PO: //由Hibernate返回的PO TUser user = (TUser)session.load(TUser.class,new Integer(1)); 总结:VO经过Hibernate进行处理,就变成了PO。 session.save(user)中,我们把一个VO “user”传递给Hibernate的Session.save方法进行保存。在save方法中,Hibernate对其进行如下处理: 1. 在当前session所对应的实体容器(Entity Map)中查询是否存在user对象 的引用。 2. 如果引用存在,则直接返回user对象id,save过程结束. Hibernate中,针对每个Session有一个实体容器(实际上是一个Map对象), 如果此容器中已经保存了目标对象的引用,那么hibernate会认为此对象已经 与Session相关联。 对于save操作而言,如果对象已经与Session相关联(即已经被加入Session 的实体容器中),则无需进行具体的操作。因为之后的Session.flush过程中, Hibernate会对此实体容器中的对象进行遍历,查找出发生变化的实体,生成 并执行相应的update语句。 3. 如果引用不存在,则根据映射关系,执行insert操作。 a) 在我们这里的示例中,采用了native的id生成机制,因此hibernate会 从数据库取得insert操作生成的id并赋予user对象的id属性。 b) 将user对象的引用纳入Hibernate的实体容器。 c) save过程结束,返回对象id. 而Session.load方法中,再返回对象之前,Hibernate就已经将此对象纳入其实 体容器中。 VO和PO的主要区别在于: VO是独立的Java Object。 PO是由Hibernate纳入其实体容器(Entity Map)的对象,它代表了与数 据库中某条记录对应的Hibernate实体,PO的变化在事务提交时将反应到实 际数据库中。 如果一个PO与Session对应的实体容器中分离(如Session关闭后的PO),那么 此时,它又会变成一个VO。 由PO、VO的概念,又引申出一些系统层次设计方面的问题。如在传统的MVC架构中, 位于Model层的PO,是否允许被传递到其他层面。由于PO的更新最终将被映射到实 际数据库中,如果PO在其他层面(如View层)发生了变动,那么可能会对Model 层造成意想不到的破坏。 因此,一般而言,应该避免直接PO传递到系统中的其他层面,一种解决办法是,通 过一个VO,通过属性复制使其具备与PO相同属性值,并以其为传输媒质(实际上, 这个VO被用作Data Transfer Object,即所谓的DTO),将此VO传递给其他层 面以实现必须的数据传送。 属性复制可以通过Apache Jakarta Commons Beanutils (http://jakarta.apache.org/commons/beanutils/)组件提供的属性批 量复制功能,避免繁复的get/set操作。 下面的例子中,我们把user对象的所有属性复制到anotherUser对象中: TUser user = new TUser(); TUser anotherUser = new TUser(); user.setName("Emma"); user.setUserType(1); try { BeanUtils.copyProperties(anotherUser,user); System.out.println("UserName => " +anotherUser.getName() ); System.out.println("UserType => " + anotherUser.getUserType() ); Hibernate Developer’s Guide Version 1.0 September 2, 2004 So many open source projects. Why not Open your Documents? } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |