聚合:是整体与部分的关系,部分可以离开整体而单独存在。如大雁和雁群,大雁离开雁群,也可以单独存在。
【UML表示法】带空心的菱形的实线。
【箭头指向】空心菱形指向整体。
组合:也是整体与部分的关系,但部分不能离开整体而单独存在。如鸟和翅膀,翅膀不能作为单独的个体存在。
【UML表示法】带实心的菱形的实线。
【箭头指向】实心菱形指向整体。
原文地址:http://www.jb51.cc/article/p-umwmtgzf-uw.html
聚合(aggregation)关系:关联关系的一种特例,是强的关联关系.聚合是整体和个体之间的关系,即has-a的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与cpu、汽车与车轮、公司与员工的关系等;表现在代码层面,和关联关系是一致的,只能从语义级别来区分;
聚合关系也是使用实例变量实现的.从java语法上是分不出关联和聚合的.
关联关系中两个类是处于相同的层次,而聚合关系中两不类是处于不平等的层次一个表示整体一个表示部分.
组合(合成)关系(composition):也是关联关系的一种特例,他体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合;他同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束;比如你和你的大脑;合成关系不能共享。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。
组合跟聚合几乎相同,唯一的区别就是“部分”不能脱离“整体”单独存在,就是说, “部分”的生命期不能比“整体”还要长。
Person类和Address类是聚合关系:
假设我们要定义这两个对象,对于每个人来说,他有一个关联的地址。人和地址的关系是has-a的关系。但是,我们不能说这个地址是这个人的一个组成部分。同时,我们建立地址对象和人的对象是可以相对独立存在的。
- publicclassAddress
- {
- ...
- }
- publicclassPerson
- {
- privateAddressaddress;
- publicPerson(Addressaddress)
- {
- this.address=address;
- }
- ...
- }
我们通常通过如下的方式来使用Person对象:
或者:
我们可以看到,我们是创建了一个独立的Address对象,然后将这个对象传入了Person的构造函数。当Person对象声明周期结束的时候,Address对象如果还有其他指向它的引用,是可能继续存在的。也就是说,他们的声明周期是相对独立的。
原文地址: http://developer.51cto.com/art/201201/311219.htm
【映射组合关系】
Name.java
package mypack; public class Name { private String firstName; private String lastName; public Name() { } public Name(String firstName,String lastName) { super(); this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
package mypack; import java.sql.Date; import java.sql.Timestamp; import java.util.HashSet; import java.util.Set; public class Customer { private Long id; private Name name; private String email; private String password; private int phone; private boolean married; private String address; private Character sex; private String description; private byte[] image; private Date birthday; private Timestamp registeredTime; private Set<Order> orders = new HashSet<Order> (); public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Name getName() { return name; } public void setName(Name name) { this.name = name; } // …… }
Hibernate把持久化类中的属性分为两种:值(Value)类型和实体(Entity)类型。
- 值类型没有OID,不能被单独持久化,它的生命周期依赖于所属的持久化类的对象的生命周期,如id(Long型)、email(String型)、name(组件类型)是值类型属性;
- 实体类型有OID,可以被单独持久化,如orders集合中的Order对象是实体类型的。
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="mypack.Customer" table="CUSTOMERS"> <id name="id" type="long"> <column name="ID" /> <generator class="native" /> </id> <component name="name" class="mypack.Name"> <property name="firstName" type="string" column="FIRST_NAME" /> <property name="lastName" type="string" column="LAST_NAME" /> </component> <!-- …… --> <set name="orders" cascade="all-delete-orphan" inverse="true" > <key column="CUSTOMER_ID" /> <one-to-many class="mypack.Order"/> </set> </class> </hibernate-mapping>
数据库表CUSTOMERS:
【映射聚合关系】
在存在数据冗余的情况下,需要把粗粒度的表拆分成具有外键参照关系的几个细粒度的表,从而节省存储空间;(持久化类、映射、数据库表等和关联关系一致)
在没有数据冗余的前提下,应该尽可能地减少表的数目,简化表之间的参照关系,以便提高访问数据库的速度。(持久化类、映射、数据库表等和组合关系一致)
建立域模型和关系数据模型有着不同的出发点。域模型事由程序代码组成的,通过细化持久化类的粒度可提高代码可重用性,简化编程;在建立关系数据模型时,需要进行节省数据存储空间和节省数据操纵时间的折中。