一对一,各种形式的单双向关联

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

共六种情况,分成两大类,每类有3个
第一类: 1对1单向关联
一对一,通过外健实现的单向关联
是M:1的特例
假设一个人只有一个办公室:
Person(pid int primary key, pname char(10), office_id int references office(id));
Office(oid int primary key, address char(10));
CREATE TABLE `person` (
`pid` int(11) NOT NULL DEFAULT '0',
`pname` char(10) DEFAULT NULL,
`office_id` int(11) DEFAULT NULL,
PRIMARY KEY (`pid`),
KEY `person_office_FK` (`office_id`),
CONSTRAINT `person_office_FK` FOREIGN KEY (`office_id`) REFERENCES `office` (`oid`) );
CREATE TABLE `office` (
`oid` int(11) NOT NULL DEFAULT '0',
`address` varchar(20) DEFAULT NULL,
PRIMARY KEY (`oid`)
)
对应的类:
public class Person {
private Integer pid;//主键
private String pname;
private Office office;//对应的办公室,单向关联
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public Office getOffice() {
return office;
}
public void setOffice(Office office) {
this.office = office;
}
}
OFFICE类:
public class Office {
private Integer oid;//Office id为主键
private String address;
public Integer getOid() {
return oid;
}
public void setOid(Integer oid) {
this.oid = oid;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
相应的映射文件:
Person.hbm.xml
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jpioneer.po.Person"table="person">
<id name="pid"type="ng.Integer">
<generator class="increment"></generator>
</id>
<property name="pname"type="ng.String">
<column name="pname"></column>
</property>
<!-- Person类中的office属性对应的列是person表中的office_id,是外键
-->
<!-- unique="true"表示一对一关系 -->
<many-to-one name="office"column="office_id"unique="true">
</many-to-one>
</class>
</hibernate-mapping>
Office.hbm.xml
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jpioneer.po.Office"table="office">
<id name="oid"type="ng.Integer">
<generator class="increment"></generator>
</id>
<property name="address" type="ng.String">
<column name="address"></column>
</property>
</class>
</hibernate-mapping>
测试:
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
Person p = new Person();
p.setPname("张三");
Office o = new Office();
o.setAddress("北京");
p.setOffice(o);
//保存的顺序与效率有关
session.save(o);
session.save(p);
mit();
session.close();
}
一对一,通过主健实现的单向关联
主健类不能主健生成策略,由关联类负责.
假设一个人只有一个办公室:
Person(pid int primary key references office(oid), pname char(10));
//注意pid既是主健也是外键
Office(oid int primary key, address char(10));
CREATE TABLE `office` (
`oid` int(11) NOT NULL DEFAULT '0',
`address` varchar(20) DEFAULT NULL,
PRIMARY KEY (`oid`)
)
CREATE TABLE `person` (
`pid` int(11) NOT NULL DEFAULT '0',
`pname` char(10) DEFAULT NULL,
PRIMARY KEY (`pid`),
CONSTRAINT `person_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `office` (`oid`)
)
对应的类:与上同。

映射:
Person.hbm.xml
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jpioneer.po.Person"table="person">
<!-- 主键生成必须为foreign, 根据关联类生成主键-->
<id name="pid"type="ng.Integer">
<generator class="foreign">
<!-- office是Person的属性,表示Person的键值由对应的类Office生成
-->
<param name="property">office</param>
</generator>
</id>
<property name="pname"type="ng.String">
<column name="pname"></column>
</property>
<!-- Person类中的office属性,1:1关联 -->
<one-to-one name="office"constrained="true"/>
</class>
</hibernate-mapping>
Office.hbm.xml无变化
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD
3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jpioneer.po.Office"table="office">
<id name="oid"type="ng.Integer">
<generator class="increment"></generator>
</id>
<property name="address" type="ng.String">
<column name="address"></column>
</property>
</class>
</hibernate-mapping>
测试:无变化
一对一,通过连接表的单向关联
这种方案比较少见,设置与通过外健实现的单向关联基本相同
数据库表:
CREATE TABLE `person` (
`pid` int(11) NOT NULL,
`pname` char(10) DEFAULT NULL,
PRIMARY KEY (`pid`)
)
CREATE TABLE `office` (
`oid` int(11) NOT NULL,
`address` varchar(20) DEFAULT NULL,
PRIMARY KEY (`oid`)
)
关联表
CREATE TABLE `person_office` (
`oid` int(11) DEFAULT NULL,
`pid` int(11) DEFAULT NULL,
KEY `FK1` (`pid`),
KEY `fk2` (`oid`),
CONSTRAINT `fk2` FOREIGN KEY (`oid`) REFERENCES `office` (`oid`),
CONSTRAINT `FK1` FOREIGN KEY (`pid`) REFERENCES `person` (`pid`)
)
Person/Office类同上
Mapping文件:
Person.hbm.xml
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jpioneer.Person"table="person">
<id name="pid"type="ng.Integer">
<generator class="increment"></generator>
</id>
<property name="pname"type="ng.String">
<column name="pname"></column>
</property>
<!-- 通过指定关联表映射关系 -->
<join table="person_office">
<key column="pid"></key>
<many-to-one name="office"column="oid"
unique="true"></many-to-one>
</join>
</class>
</hibernate-mapping>
Office.hbm.xml
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jpioneer.Office"table="office">
<id name="oid"type="ng.Integer">
<generator class="increment"></generator>
</id>
<property name="address"type="ng.String">
<column name="address"></column>
</property>
</class>
</hibernate-mapping>
测试同上。

第二类: 1对1双向关联
一对一,通过连接表的双向关联
数据库表同一对一,通过连接表的单向关联
类:
public class Person {
private Integer pid;//主键
private String pname;
private Office office;//对应的办公室
}
public class Office {
private Integer oid;//Office id为主键
private String address;
private Person person;//对应的人
}
映射:
Person.hbm.xml
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jpioneer.Person"table="person">
<id name="pid"type="ng.Integer">
<generator class="increment"></generator>
</id>
<property name="pname"type="ng.String">
<column name="pname"></column>
</property>
<!-- 通过指定关联表映射关系 -->
<join table="person_office">
<key column="pid"unique="true"></key>
<many-to-one name="office"column="oid"
unique="true"></many-to-one>
</join>
</class>
</hibernate-mapping>
Office.hbm.xml
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jpioneer.Office"table="office">
<id name="oid"type="ng.Integer">
<generator class="increment"></generator>
</id>
<property name="address"type="ng.String">
<column name="address"></column>
</property>
<join table="person_office"inverse="true">
<key column="oid"unique="true"></key>
<many-to-one name="person"column="pid"
unique="true"></many-to-one>
</join>
</class>
</hibernate-mapping>
一对一,通过主健实现的双向关联(应用稍多)
数据库表格同通过主健实现的单向关联
CREATE TABLE `person` (
`pid` int(11) NOT NULL DEFAULT '0',
`pname` char(10) DEFAULT NULL,
PRIMARY KEY (`pid`),
CONSTRAINT `person_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `office` (`oid`)
)
CREATE TABLE `office` (
`oid` int(11) NOT NULL DEFAULT '0',
`address` varchar(20) DEFAULT NULL,
PRIMARY KEY (`oid`)
)
类同其他双向关联
public class Person {
private Integer pid;//主键
private String pname;
private Office office;//对应的办公室
}
public class Office {
private Integer oid;//Office id为主键
private String address;
private Person person;//对应的人
}
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jpioneer.Person"table="person">
<!-- 主键生成必须为foreign, 根据关联类生成主键-->
<id name="pid"type="ng.Integer">
<generator class="foreign">
<!-- office是Person的属性,表示Person的键值由对应的类Office生成
-->
<param name="property">office</param>
</generator>
</id>
<property name="pname"type="ng.String">
<column name="pname"></column>
</property>
<!-- Person类中的office属性,1:1关联 -->
<one-to-one name="office"constrained="true"/>
</class>
</hibernate-mapping>
<?xml version="1.0"encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.jpioneer.Office"table="office">
<id name="oid"type="ng.Integer">
<generator class="increment"></generator>
</id>
<property name="address"type="ng.String">
<column name="address"></column>
</property>
<!-- cascade="all":在保存office对象的时候,级联保存office对象关联的person对象 -->
<one-to-one name="person" cascade="all"/>
</class>
</hibernate-mapping>
public class Test {
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
Person p = new Person();
p.setPname("张三");
Office o = new Office();
o.setAddress("北京");
p.setOffice(o);
o.setPerson(p);
session.save(o);//由于使用了cascade=”all”
//session.save(p);
mit();
session.close();
}
}
一对一,通过外健实现的双向关联
只是在多方实施一个唯一性约束。

相关文档
最新文档