在域模型中,有些类由几个部分类组成(创建部分类是因为它们是可以重用的),部分类对象的生命周期依赖于整体类对象的生命周期,这种整体与部份的关系称为聚集关系.如电脑它可以由主机器,键盘等类组成.主机箱又由显示卡,声卡等类组成.
建立精粒度对象模型
假如在Customer 类中有代表家庭地址以及公司的地址的属性,地址划分为省、市、街道和邮编,为了提高代码重用性,把从Customer类中抽象出地址类Address,然后在Customer类中建立Address类型的homeAddress和comAddress属性
建立粗粒度关系数据模型
建立关系数据模型的一个重要原则是不要导致数据冗余,同时尽可能减少数据表的数目和表之间的外键参照关系(在更新数据时,不需建立多表连接,提高性能).如果为8.1中的Customer和Address都建立一张表,通过主外键关系,在每次查询客户信息时,都要进行两表连接.解决方法:把两个ADDRESS表的字段都放到CUSTOMER表中去,它们是聚集关系,并不产生数据冗余
映射组成关系
建立域模型讲究代码的重用性,简化编程;而关系模型讲究数据冗余、在没有冗余的前提下应减少表的数目和表之间的关联。最终把上面的问题解决方案化为以下图示:
这样怎么映射呢?要使用<component>元素,Customer类的映射代码如下:
<component name=”homeAddress” class=”mypack.Address”>
<parent name=”customer”/>
<property name=”street” type=”string” column=”HOME_STREET”/>
<property name=”city” type=”string” column=”HOME_CITY”/>
<property name=”province” type=”string” column=”HOME_PROVINCE”/>
<property name=”zipcode” type=”short” column=”HOME_ZIPCODE”/>
</component>
<component name=”comAddress” class=”mypack.Address”>
<parent name=”customer”/>
<property name=”street” type=”string” column=”COM_STREET”/>
<property name=”city” type=”string” column=” COM _CITY”/>
<property name=”province” type=”string” column=” COM _PROVINCE”/>
<property name=”zipcode” type=”short” column=” COM _ZIPCODE”/>
</component>
区分值(value)类型和实体(entity)类型
Address类没有OID,这是Hibernate组件的重要特征,也就不可以通过Session来单独保存、更新、删除或加载一个Address对象,它和类中的String name,int age等是值类型,而Set orders,Company currentCompany是实体类型(它们在单独的表,有单独的有OID的类)
在应用程序中访问具有组成关系的持久化类
1.在初始化Hibernate时:config.addClass(Customer.class);不要加载Address.class组件类
2.保存持久化类
tx=session.beginTransaction();
Customer customer=new Customer();
Address homeAddress
=new Address(“province1”,”city1”,”street1”,”100001”,customer);
Address comAddress
=new Address(“province2”,”city2”,”street1”,”200002”,customer);
customer.setName=”Tom”;
customer.setHomeAddress(homeAddress);
customer.setComAddress(comAddress);
session.save(customer);
tx.commit();
如果Address comAddress=new Address(null, null, null, null,null);那么:
Address comAddress=customer.getComAddress();结果comAddress=null
3.删除Customer对象
tx=session.beginTransaction();
session.delete(customer);
tx.commit();
映射复合组成关系
组件包含组件,组件和其他实体类关联,如下图,怎么映射?
如下是Computer.hbm.xml文件
<component name=”cpuBox” class=”mypack.CPUBox”>
<parent name=”computer”/>
<property name=”type” type=”string”>
<column name=”CPUBOX_TYPE” length=”15”/>
</property>
<many-to-one name=”vendor” column=”CUPBOX_VENDOR_ID” class=”vendor”/>
//嵌套的component
< component name=”graphicsCard” class=”mypack.GraphicsCard”>
< parent name=”computer”/>
<property name=”type” type=”string”>
<column name=”GRAPHICSCARD_TYPE” length=”15”/>
</property>
</component>
</component>