Hibernate 映射一对一关联关系
2016-02-24 16:56
260 查看
之前介绍组成关系时,已介绍了Customer类与Address类,Address类是组件类,没有OID,数据库中没有对应的表, Address对象的生命周期依赖于Customer对象的生命周期。Customer类中定义了两个值类型的homeAddress属性和comAddress属性:
Hibernate提供两种映射一对一关联关系的方法:按照外键映射和按照主键映射。
数据库表:
create table CUSTOMERS (
ID bigint not null,
NAME varchar(15),
HOME_ADDRESS_ID bigint unique,
COM_ADDRESS_ID bigint unique,
primary key (ID),
foreign key (HOME_ADDRESS_ID) references ADDRESSES(ID),
foreign key (COM_ADDRESS_ID) references ADDRESSES(ID)
);
create table ADDRESSES(
ID bigint not null,
CITY varchar(128),
STREET varchar(128),
PROVINCE varchar(128),
ZIPCODE varchar(6),
primary key(ID)
);
Customer.java:
public class Customer implements Serializable {
private Long id;
private String name;
private Address homeAddress;
private Address comAddress;
constructor...(); getter()...;setter()...;
}
Customer.hbm.xml:
<hibernate-mapping >
<class name="mypack.Customer" table="CUSTOMERS" >
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" column="NAME" type="string" />
<many-to-one name="homeAddress"
class="mypack.Address"
column="HOME_ADDRESS_ID"
cascade="all"
unique="true"
/>
<many-to-one name="comAddress"
class="mypack.Address"
column="COM_ADDRESS_ID"
cascade="all"
unique="true"
/>
</class>
</hibernate-mapping>
<many-to-one>元素的unique为true,表明每个Customer对象都有唯一的homeAddress和comAddress对象。
Address.java:
<hibernate-mapping >
<class name="mypack.Address" table="ADDRESSES" >
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="city" column="CITY" type="string" />
<property name="province" column="PROVINCE" type="string" />
<property name="street" column="STREET" type="string" />
<property name="zipcode" column="ZIPCODE" type="string" />
<one-to-one name="customer"
class="mypack.Customer"
property-ref="homeAddress"
/>
</class>
</hibernate-mapping>
<one-to-one>元素的property-ref属性为"homeAddress",表明建立了从homeAddress对象到Customer对象的关联。
只能用<one-to-one>元素对Address类的customer属性映射一次,已映射homeAddress对象与Customer对象的双向关联,不能同时再映射Customer对象与comAddress对象的双向关联。
解决办法:把Address类定义为抽象类,创建HomeAddress和ComAddress子类,在HomeAddress.hbm.xml和ComAddress.hbm.xml中分别用<one-to-one>元素来映射各自的customer属性。
默认情况下,多对一关联采用延迟检索策略,一对一关联采用迫切左连接检索策略。
数据库表:
create table CUSTOMERS (
ID bigint not null,
NAME varchar(15),
primary key (ID)
);
create table ADDRESSES(
ID bigint not null,
STREET varchar(128),
CITY varchar(128),
PROVINCE varchar(128),
ZIPCODE varchar(6),
primary key (ID),
foreign key (ID) references CUSTOMERS(ID)
);
Customer.java:
<hibernate-mapping >
<class name="mypack.Customer" table="CUSTOMERS" >
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" column="NAME" type="string" />
<one-to-one name="address"
class="mypack.Address"
cascade="all"
/>
</class>
</hibernate-mapping>
Address.java:
<hibernate-mapping >
<class name="mypack.Address" table="ADDRESSES" >
<id name="id" type="long" column="ID">
<generator class="foreign">
<param name="property">customer</param>
</generator>
</id>
<property name="city" column="CITY" type="string" />
<property name="province" column="PROVINCE" type="string" />
<property name="street" column="STREET" type="string" />
<property name="zipcode" column="ZIPCODE" type="string" />
<one-to-one name="customer"
class="mypack.Customer"
constrained="true"
/>
</class>
</hibernate-mapping>
<one-to-one>元素的constrained属性为true,表明ADDRESSES表的ID主键同时作为外键参照CUSTOMERS表,此时其OID必须使用foreign标识符生成策略。
使用foreign标识符生成策略,Hibernate会保证Address对象与关联的Customer对象共享同一个OID。
private Address homeAddress; private Address comAddress;但也可以将Address设计成实体类,此时,数据库中存在ADDRESSES表,Address类有单独的OID,Customer类与Address类之间为一对一的关联关系。
Hibernate提供两种映射一对一关联关系的方法:按照外键映射和按照主键映射。
1.按照外键映射
CUSTOMERS表的两个外键HOME_ADDRESS_ID和COM_ADDRESS_ID都参照ADDRESSES表的主键。数据库表:
create table CUSTOMERS (
ID bigint not null,
NAME varchar(15),
HOME_ADDRESS_ID bigint unique,
COM_ADDRESS_ID bigint unique,
primary key (ID),
foreign key (HOME_ADDRESS_ID) references ADDRESSES(ID),
foreign key (COM_ADDRESS_ID) references ADDRESSES(ID)
);
create table ADDRESSES(
ID bigint not null,
CITY varchar(128),
STREET varchar(128),
PROVINCE varchar(128),
ZIPCODE varchar(6),
primary key(ID)
);
Customer.java:
public class Customer implements Serializable {
private Long id;
private String name;
private Address homeAddress;
private Address comAddress;
constructor...(); getter()...;setter()...;
}
Customer.hbm.xml:
<hibernate-mapping >
<class name="mypack.Customer" table="CUSTOMERS" >
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" column="NAME" type="string" />
<many-to-one name="homeAddress"
class="mypack.Address"
column="HOME_ADDRESS_ID"
cascade="all"
unique="true"
/>
<many-to-one name="comAddress"
class="mypack.Address"
column="COM_ADDRESS_ID"
cascade="all"
unique="true"
/>
</class>
</hibernate-mapping>
<many-to-one>元素的unique为true,表明每个Customer对象都有唯一的homeAddress和comAddress对象。
Address.java:
public class Address 4000 implements Serializable { private Long id; private String street; private String city; private String province; private String zipcode; private Customer customer; constructor...(); getter()...;setter()...; }Address.hbm.xml:
<hibernate-mapping >
<class name="mypack.Address" table="ADDRESSES" >
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="city" column="CITY" type="string" />
<property name="province" column="PROVINCE" type="string" />
<property name="street" column="STREET" type="string" />
<property name="zipcode" column="ZIPCODE" type="string" />
<one-to-one name="customer"
class="mypack.Customer"
property-ref="homeAddress"
/>
</class>
</hibernate-mapping>
<one-to-one>元素的property-ref属性为"homeAddress",表明建立了从homeAddress对象到Customer对象的关联。
只能用<one-to-one>元素对Address类的customer属性映射一次,已映射homeAddress对象与Customer对象的双向关联,不能同时再映射Customer对象与comAddress对象的双向关联。
解决办法:把Address类定义为抽象类,创建HomeAddress和ComAddress子类,在HomeAddress.hbm.xml和ComAddress.hbm.xml中分别用<one-to-one>元素来映射各自的customer属性。
默认情况下,多对一关联采用延迟检索策略,一对一关联采用迫切左连接检索策略。
2.按照主键映射
ADDRESSES表的ID即作为主键,又作为外键参照CUSTOMERS表的主键,即ADDRESSES表与CUSTOMERS表共享主键。数据库表:
create table CUSTOMERS (
ID bigint not null,
NAME varchar(15),
primary key (ID)
);
create table ADDRESSES(
ID bigint not null,
STREET varchar(128),
CITY varchar(128),
PROVINCE varchar(128),
ZIPCODE varchar(6),
primary key (ID),
foreign key (ID) references CUSTOMERS(ID)
);
Customer.java:
public class Customer implements Serializable { private Long id; private String name; private Address address; constructor...(); getter()...;setter()...; }Customer.hbm.xml:
<hibernate-mapping >
<class name="mypack.Customer" table="CUSTOMERS" >
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" column="NAME" type="string" />
<one-to-one name="address"
class="mypack.Address"
cascade="all"
/>
</class>
</hibernate-mapping>
Address.java:
public class Address implements Serializable { private Long id; private String street; private String city; private String province; private String zipcode; private Customer customer; constructor...(); getter()...;setter()...; }Address.hbm.xml:
<hibernate-mapping >
<class name="mypack.Address" table="ADDRESSES" >
<id name="id" type="long" column="ID">
<generator class="foreign">
<param name="property">customer</param>
</generator>
</id>
<property name="city" column="CITY" type="string" />
<property name="province" column="PROVINCE" type="string" />
<property name="street" column="STREET" type="string" />
<property name="zipcode" column="ZIPCODE" type="string" />
<one-to-one name="customer"
class="mypack.Customer"
constrained="true"
/>
</class>
</hibernate-mapping>
<one-to-one>元素的constrained属性为true,表明ADDRESSES表的ID主键同时作为外键参照CUSTOMERS表,此时其OID必须使用foreign标识符生成策略。
使用foreign标识符生成策略,Hibernate会保证Address对象与关联的Customer对象共享同一个OID。
相关文章推荐
- Android6.0权限问题导致下载没效果
- 89. Gray Code
- POJ-2492(并查集问题)
- SQL复习总结——DQL,聚合函数与分组
- 排序——选择排序(Selectsort)
- Java集群优化——dubbo+zookeeper构建高可用分布式集群
- arduino IO口
- jQuery验证控件jquery.validate.js使用说明+中文API
- 百度地图官网中的示例错误
- ASP.NET网站 文件的上传与下载(二)
- 快速Android开发系列网络篇之Retrofit
- MongoDB 优化器profile
- UVA 12664(BFS)
- 设计模式学习总结
- ElasticSearch 2 (7) - 基本概念
- 1037. Magic Coupon (25)
- solr的搭建
- Admob Unity Package在Unity3.2上工作
- myeclipse 2015 下载 安装 配置
- Zabbix集成OneAlert实现短信、邮件、微信、电话、App告警