Hibernate 如何区别 “实体对象” 和 “值对象” ,如何用?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate 如何区别 “实体对象” 和 “值对象” ,如何用?相关的知识,希望对你有一定的参考价值。

值对象和实体对象是hibernate的重要概念,当然在jpa中也有相应的概念他们在语义上是相同的。常常听到人们抱怨hibernate中对象之间的映射关系配置很难,而且经常出现一些莫名奇妙的问题。其真正原因是没有正确的区分值对象和实体对象而进行了错误的设计(其实很多就没有值对象的概念,而在系统将所有的对象都归结为了实体)。
一、什么是值对象?
举个例子:如果用User类和Address类,对于每个具体的User有对应的Address,当然这个Address可以是多个(家庭地址、公司地址)等等。而这些地址只能依赖于User类而存在,并且不存在其他对象对某个具体Address的引用(此处忽略,两个人有同一地址的情况)。这时候Address就是一个值对象。
更抽象的,对于一个实体如何区分是值对象和实体对象主要从一下三点考虑
1、是否有一个依赖的生命周期,如果此对象依赖于另一个对象的生灭,就认为他是有一个依赖的生命周期的。
2、是否需要它们自己的同一性(java中体现为 == 和 equals() 方法,数据库中体现为主键是否相等),就是说你的代码中会不会去比较两个对象是否具有同一性,
在上例中体现为我们永远不会去比较连个地址是否相等(== 或者 equlas());
3、是否需要支持共享引用。
如果一个对象有一个依赖的生命周期,不需要它们自己的同一性,并且不必支持共享引用的话它就是个值类型的对象。
例如:报销单下有报销明细,报销明细就是一个值对象,再如一个商品有它的多张照片,照片就是值对象,更一般的java中的String,Integer,Double.....都是值对象
二、为什么要使用值对象。
Hibernate对值对象的的映射提供了特别的支持,如果你有一个1对多的关联,而且你希望在1的一方控制一切的话,更具经验多数情况下多的一方是一个值对象。如果是值对象你可以避免考虑级联更新的问题,孤儿的问题等等。而交给hibernate去控制
常见值对象集合的映射如下:(已商品和图像(路径)为例)
set:
<set name="images" table="ITEM_IMAGE">
<key column="Item_id"/>
<element type="string" column="filename" not-null="true"/>
</set>
list
<list name="images" table="ITEM_IMAGE">
<key column="Item_id"/>
<list-index column="prosition"/>
<element type="string" column="filename" not-null="true"/>
</set>
map
<map name="images" table="ITEM_IMAGE">
<key column="Item_id"/>
<map-index column="imagename" type="stirng"/>
<element type="string" column="filename" not-null="true"/>
</map>
参考技术A   对于一个实体如何区分是值对象和实体对象主要从以下三点区分:
  1、是否有一个依赖的生命周期,如果此对象依赖于另一个对象的生灭,就认为他是有一个依赖的生命周期的。
  2、是否需要它们自己的同一性(java中体现为 == 和 equals() 方法,数据库中体现为主键是否相等),就是说你的代码中会不会去比较两个对象是否具有同一性,
  在上例中体现为我们永远不会去比较两个地址是否相等(== 或者 equlas());
  3、是否需要支持共享引用。
  如果一个对象有一个依赖的生命周期,不需要它们自己的同一性,并且不必支持共享引用的话它就是个值类型的对象。
参考技术B 对于一个实体如何区分是值对象和实体对象主要从以下三点区分:
1、是否有一个依赖的生命周期,如果此对象依赖于另一个对象的生灭,就认为他是有一个依赖的生命周期的。
2、是否需要它们自己的同一性(java中体现为 == 和 equals() 方法,数据库中体现为主键是否相等),就是说你的代码中会不会去比较两个对象是否具有同一性,
在上例中体现为我们永远不会去比较两个地址是否相等(== 或者 equlas());
3、是否需要支持共享引用。
如果一个对象有一个依赖的生命周期,不需要它们自己的同一性,并且不必支持共享引用的话它就是个值类型的对象。
参考技术C 实体是数据的一种载体,传递数据用的,在三层架构中,会分一个实体层,数据库中的每一张表那叫实体集,所以在程序中为了消除数据库的关系模型,使之面向对象,所谓实体对像就是实体类的一个实例。
值对象是否需要存储而导致了值对象的不同创建策略,如果需要存储,说明这个值对象代表的规格是需要一再复用的,同时也是可以配置和修改的,创建采用读写文件形成,有需要的话可以结合反射技术。 如果不需要存储,说明是固化在代码中,对应的计算相对固定。
对于一个实体如何区分是值对象和实体对象主要从以下三点区分:
1、是否有一个依赖的生命周期,如果此对象依赖于另一个对象的生灭,就认为他是有一个依赖的生命周期的。
2、是否需要它们自己的同一性(java中体现为 == 和 equals() 方法,数据库中体现为主键是否相等),就是说代码中会不会去比较两个对象是否具有同一性,
在上例中体现为永远不会去比较两个地址是否相等(== 或者 equlas());
3、是否需要支持共享引用。
如果一个对象有一个依赖的生命周期,不需要它们自己的同一性,并且不必支持共享引用的话它就是个值类型的对象。

以上是关于Hibernate 如何区别 “实体对象” 和 “值对象” ,如何用?的主要内容,如果未能解决你的问题,请参考以下文章

hibernate实体对象的三种状态:自由状态,持久状态,游离状态.

Hibernate的Session的get()和load()方法区别

Hibernate 关于load和get方法区别

Hibernate中get和load的区别

hibernate延迟加载(get和load的区别)

Hibernate中get()和load()方法的区别