Hibernate关系映射

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

word
目录
1关系映射1
1.1单向关联1
1.1.1 一对一外键单向关联1
1.1.2 一对一主键单向关联5
1.1.3 一对多外键单向关联6
1.1.4 多对一外键单向关联10
1.2双向关联14
1.2.1 一对一外键双向关联14
1.2.2 一对一主键双向关联17
1.2.3 一对多外键双向关联18
1.2.4 多对多双向关联21
1关系映射1.1单向关联
1.1.1一对一外键单向关联
1、模型介绍
一个人〔Person〕对应一个地址〔Address〕。

2、实体〔无getter和setter〕
Peron
private Long oid;
private String personid;
private String name;
private Address addressfk;
Address
private Long oid;
private String addressid;
private String addressdetail;
3、表模型
以下是地址表
表1地址表
以下是人物表,其中addressid是外键引用地址表的addressid
表2人物表
4、映射文件
<hibernate-mapping package=".test.fkoo">
<class name="Address" table="address">
<id name="oid">
<generator class="native" />
</id>
<property name="addressid" unique="true" not-null="true" /> <property name="addressdetail" not-null="true" />
</class>
</hibernate-mapping>
<hibernate-mapping package=".test.fkoo">
<class name="Person" table="person">
<id name="oid">
<generator class="native" />
</id>
<property name="personid" unique="true" not-null="true" />
<property name="name" not-null="true" />
<!--用来映射关联PO column是Address在该表中的外键列名,增加unique 是唯一的-->
<!--下面的addressid只是名字而已,manytoone自动关联address方的主键不过取个有实际意义的名字让表结构更清晰-->
<many-to-one name="addressfk" column="addressid" unique="true" not-null="true"/>
</class>
</hibernate-mapping>
5、测试方法
public class Test {
public static void main(String[] args) {
Session s = HibernateUtil.getSession();
try {
s.beginTransaction();
Person p = new Person();
p.setName("xuwei");
p.setPersonid("200610801232");
Address a = new Address();
a.setAddressid("杨家冲6号");
a.setAddressdetail("某某市大安区");
p.setAddressfk(a);
s.save(a);
s.save(p);
s.getTransaction().mit();
} catch (HibernateException e) {
e.printStackTrace();
s.getTransaction().rollback();
} finally {
s.close();
}
}
}
6、测试结果
a、s.save(a);s.save(p);
正常保存
b、s.save(p);s.save(a);
异常发生,异常信息:
not-null property references a null or transient value c、s.save(a)
能够插入,但信息不全,只插入一条记录。

d、s.save(p)
异常发生,异常信息:
not-null property references a null or transient value
1.1.2一对一主键单向关联
1、要改的地方只有一个就是
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"/hibernate-mapping-3.0.dtd">
<hibernate-mapping package=".test.pkoo">
<class name="Person" table="person">
<id name="oid" column="oid">
<!--基于主键关联时,主键生成策略是foreign,明确根据关联类生成主键-->
<generator class="foreign">
<!--关联持久化类的属性名-->
<param name="property">addressfk</param>
</generator>
</id>
<property name="personid" unique="true" not-null="true" />
<property name="name" not-null="true" />
<!--用于映射1-1关联-->
<one-to-one name="addressfk" constrained="true" />
</class>
</hibernate-mapping>
2、测试结果
a、s.save(a);s.save(p);
正常保存,推荐方式,先插入父表,再插入子表
b、s.save(p);s.save(a);
正常保存,也是先插入父表,再插入子表
c、s.save(a)
能够插入,但信息不全,只插入一条记录。

d、s.save(p)
正常保存,而且插入两条记录。

1.1.3一对多外键单向关联
1、模型介绍
一个人〔Person〕对应多个地址〔Address〕,比如家庭地址、公司地址。

2、实体
Address
private Long aid;
private String addressid;
private String addressdetail;
Person
private Long pid;
private String personid;
private String name;
private Set<Address> addresses = new HashSet<Address>(); 3、表模型
以下是地址表此表是多的一方pid为外键
表3地址表
以下是人物表
表4人物表
4、映射文件
<hibernate-mapping package=".test.fkom">
<class name="Address" table="address">
<id name="aid">
<generator class="native" />
</id>
<property name="addressid" unique="true" not-null="true" /> <property name="addressdetail" not-null="true" />
</class>
</hibernate-mapping>
<hibernate-mapping package=".test.fkom">
<class name="Person" table="person">
<id name="pid">
<generator class="native" />
</id>
<property name="personid" unique="true" not-null="true" />
<property name="name" not-null="true" />
<!--
映射集合属性,关联到持久化类,inverse="false"表示主控端在Person表端,lazy="false"表示不采用延迟加载
-->
<set name="addresses" table="address" cascade="all" >
<!--确定关联的外键列-->
<key column="pid" />
<!--用以映射到关联类属性-->
<one-to-many class="Address" />
</set>
</class>
</hibernate-mapping>
5、测试方法
public class Test {
public static void main(String[] args) {
Session s = HibernateUtil.getSession(); try {
s.beginTransaction();
Person p = new Person();
Address a1 = new Address();
Address a2 = new Address();
a1.setAddressid("杨家1号");
a1.setAddressdetail("某某市大安区");
a2.setAddressid("杨家2号");
a2.setAddressdetail("某某市大安区"); p.setName("xuwei");
p.setPersonid("1");
p.getAddresses().add(a1);
p.getAddresses().add(a2);
s.save(a1);
s.save(a2);
s.save(p);
s.getTransaction().mit();
} catch (HibernateException e) {
e.printStackTrace();
s.getTransaction().rollback();
} finally {
s.close();
}
}
6、测试结果
a、s.save(a1);s.save(a2); s.save(p);
正常保存,信息:
Hibernate: insert into address (addressid, addressdetail) values (?, ?)
Hibernate: insert into address (addressid, addressdetail) values (?, ?)
Hibernate: insert into person (personid, name) values (?, ?)
Hibernate: update address set pid=? where aid=?
Hibernate: update address set pid=? where aid=?
b、s.save(p)
正常保存,同上。

c、s.save(a1);s.save(a2);
正常保存,但信息不全:
Hibernate: insert into address (addressid, addressdetail) values (?, ?)
Hibernate: insert into address (addressid, addressdetail) values (?, ?)
1.1.4多对一外键单向关联
1、模型介绍
多个人〔Person〕对应一个地址〔Address〕。

2、实体
Address
private Long oid;
private String addressid;
private String addressdetail;
Person
private Long oid;
private String personid;
private String name;
private Address addressfk;
3、表模型
以下是地址表
表5地址表
以下是人物表,多个人对应一个地址:
表6人物表
4、映射文件
<hibernate-mapping package=".test.fkmo">
<class name="Person" table="person">
<id name="pid">
<generator class="native" />
</id>
<property name="personid" unique="true" not-null="true" /> <property name="name" not-null="true" />
<!--用来映射关联PO column是Address在该表中的外键列名--> <many-to-one name="addressfk" column="addressid" />
</class>
</hibernate-mapping>
5、测试方法
Person p1 = new Person();
Person p2 = new Person();
Address a = new Address();
p1.setName("xuwei");
p1.setPersonid("001");
p2.setName("weixu");
p2.setPersonid("002");
a.setAddressid("杨家1号");
a.setAddressdetail("某某市大安区");
p1.setAddressfk(a);
p2.setAddressfk(a);
s.save(a);
s.save(p1);
s.save(p2);
6、测试结果
a、s.save(a); s.save(p1); s.save(p2);
正常保存,信息为:
Hibernate: insert into address (addressid, addressdetail) values (?, ?)
Hibernate: insert into person (personid, name, addressid) values (?, ?, ?)
Hibernate: insert into person (personid, name, addressid) values (?, ?, ?)
b、s.save(p1); s.save(p2); s.save(a);
正常保存,信息:
Hibernate: insert into person (personid, name, addressid) values (?, ?, ?)
Hibernate: insert into person (personid, name, addressid) values (?, ?, ?)
Hibernate: insert into address (addressid, addressdetail) values (?, ?)
Hibernate: update person set personid=?, name=?, addressid=? where pid=?
Hibernate: update person set personid=?, name=?, addressid=? where pid=?
c、s.save(p1); s.save(p2);
发生异常,异常信息:
Hibernate: insert into person (personid, name, addressid) values (?, ?, ?)
Hibernate: insert into person (personid, name, addressid) values (?, ?, ?)
org.hibernate.TransientObjectException: object references an unsaved transient instance
1.2双向关联
1.2.1一对一外键双向关联
1、模型介绍
同一对一单向关联
2、实体
Person
private Long oid;
private String name;
private Address addressfk;
Address
private Long oid;
private String addressdetail;
private Person personfk;
3、表模型
表7address表
表8person表
3、映射文件
<hibernate-mapping package=".test.eachoo">
<class name="Address" table="address">
<id name="oid">
<generator class="native" />
</id>
<property name="addressdetail" not-null="true" />
<!--外键方,外键一列名为personid,自动引用Person的oid作为外键--> <many-to-one name="personfk" column="personid" unique="true"
not-null="true"></many-to-one>
</class>
</hibernate-mapping>
<hibernate-mapping package=".test.eachoo">
<class name="Person" table="person">
<id name="oid">
<generator class="native" />
</id>
<property name="name" not-null="true" />
<!-- 主表方cascade=〞all〞表示级联更新和删除可以添加属性property-ref="personfk",其中personfk为Address.hbm.xml中的many-to-one的name-->
<one-to-one name="addressfk" cascade="all" ></one-to-one>
</class>
</hibernate-mapping>
4、测试
Person p = new Person();
p.setName("xuwei");
Address a = new Address();
a.setAddressdetail("某某市大安区");
p.setAddressfk(a);
a.setPersonfk(p);
s.save(p);
5、测试结果
a、p.setAddressfk(a);a.setPersonfk(p);s.save(p);
正常保存,信息如下:
Hibernate: insert into person (name) values (?)
Hibernate: insert into address (addressdetail, personid) values (?, ?)
b、p.setAddressfk(a);a.setPersonfk(p);s.save(a);
异常抛出,信息如下:
not-null property references a null or transient value
1.2.2一对一主键双向关联
1、需要改动的地方就是
<hibernate-mapping package=".test.eachpkoo">
<class name="Address" table="address">
<id name="oid">
<generator class="foreign">
<param name="property">personfk</param>
</generator>
</id>
<property name="addressdetail" not-null="true" />
<!-- 表示在address表存在一个外键约束,外键参考相关联的表person -->
<one-to-one name="personfk" constrained="true" />
</class>
</hibernate-mapping>
1.2.3一对多外键双向关联
1、模型介绍
一个人〔Person〕对于多个地址〔Address〕
2、实体
Address
private Long oid;
private String addressdetail;
private Person personfk;
Person
private Long oid;
private String name;
private Set<Address> addresses = new HashSet<Address>();
3、表模型
表9address表
表10person表
4、映射文件
<hibernate-mapping package=".test.eachfkom">
<class name="Address" table="address">
<id name="oid">
<generator class="native" />
</id>
<property name="addressdetail" not-null="true" />
<!--映射关联属性,column属性指定外键列名-->
<many-to-one name="personfk" class="Person" fetch="select" cascade="save-update" column="fid" />
</class>
</hibernate-mapping>
<hibernate-mapping package=".test.eachfkom">
<class name="Person" table="person">
<id name="oid">
<generator class="native" />
</id>
<property name="name" not-null="true" />
<!--映射集合属性,关联到持久化类-->
<set name="addresses" inverse="true" cascade="all">
<!--column用于指定外键列名-->
<key column="fid" not-null="true" /> <!--映射关联类-->
<one-to-many class="Address" />
</set>
</class>
</hibernate-mapping>
5、测试方法
s.beginTransaction();
Person p = new Person();
Address a1 = new Address();
Address a2 = new Address();
a1.setAddressdetail("某某市大安区"); a2.setAddressdetail("某某市大安区"); p.setName("xuwei");
p.getAddresses().add(a1);
p.getAddresses().add(a2);
a1.setPersonfk(p);
a2.setPersonfk(p);
s.save(p);
s.saveOrUpdate(a1);
s.saveOrUpdate(a2);
s.getTransaction().mit();
6、测试结果
s.save(p);
s.saveOrUpdate(a1);
s.saveOrUpdate(a2);
或者
s.save(p);
或者
s.saveOrUpdate(a1);
s.saveOrUpdate(a2);
均能正常保存
1.2.4多对多双向关联
1、模型介绍
多个人〔Person〕对应多个地址〔Address〕。

一个人可对应多个地址,一个地址也可以对应多个人。

2、实体
Address
private Long oid;
private String addressdetail;
private Set<Person> persons=new HashSet<Person>();
Person
private Long oid;
private String name;
private Set<Address> addresses = new HashSet<Address>();
3、表模型
表11Address表
表12Person表
表13中间关系表
4、映射文件
<hibernate-mapping package=".test.eachmm">
<class name="Person" table="person">
<id name="oid">
<generator class="native" />
</id>
<property name="name" not-null="true" />
<!--映射集合属性,关联到持久化类-->
<!--table="third"指定了连接表的名字-->
<set name="addresses" table="third_mid" cascade="all"> <!--column="personid"指定连接表中关联当前实体类的列名--> <key column="personid" not-null="true" />
<!--column="addressid"是连接表中关联本实体的外键-->
<many-to-many column="addressid" class="Address" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping package=".test.eachmm">
<class name="Address" table="address">
<id name="oid">
<generator class="native" />
</id>
<property name="addressdetail" not-null="true" />
<!--table="third"是双向多对多的连接表-->
<set name="persons" inverse="true" table="third_mid">
<!--column="addressid"是连接表中关联本实体的外键-->
<key column="addressid" />
<many-to-many column="personid" class="Person" />
</set>
</class>
</hibernate-mapping>
5、测试方法
s.beginTransaction();
Person p1= new Person();
Person p2= new Person();
Address a1 = new Address();
Address a2 = new Address();
a1.setAddressdetail("某某市大安区"); a2.setAddressdetail("内江市威远县"); p1.setName("xuwei");
p2.setName("weixu");
p1.getAddresses().add(a1);
p1.getAddresses().add(a2);
p2.getAddresses().add(a2);
a1.getPersons().add(p1);
a2.getPersons().add(p1);
a2.getPersons().add(p2);
s.save(p1);
s.save(p2);
// s.saveOrUpdate(a1);
// s.saveOrUpdate(a2);
s.getTransaction().mit();
6、测试结果
a、s.save(p1); s.save(p2);
正常保存,信息:
Hibernate: insert into person (name) values (?)
Hibernate: insert into address (addressdetail) values (?) Hibernate: insert into address (addressdetail) values (?) Hibernate: insert into person (name) values (?)
Hibernate: insert into third_mid (personid, addressid) values (?, ?) Hibernate: insert into third_mid (personid, addressid) values (?, ?) Hibernate: insert into third_mid (personid, addressid) values (?, ?)
徐伟
联系方法:无。

相关文档
最新文档