一、总体来分有一对一、一对多、多对一、多对多这四种关系。
二、一对一关系
1、单向主键
2、单向外键
具体需求是Husband实体中保存Wife的引用,得到husband的实体后就可以取得wife实体。且关系是一对一。
Husband实体简略信息
private int id;
private String name;
private int age;
private Wife wife;
Wife实体简略信息
private int id;
private String name;
现在使用xml构建从husband到wife的一对一关联,xml中使用的是<many-to-one>标签,理解的大概是外键一般都是保存在多这一方,站在当前实体husband的位置上考虑,即保存引用的这一方,这样就存在关联的关系,之后加上加上unique属性进行限定为一对一的关系。(多对一的特殊情况)
<hibernate-mapping>
<class name="com.akwolf.bean.Husband" table="HUSBAND">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="age" type="int">
<column name="AGE" />
</property>
<many-to-one name="wife" class="com.akwolf.bean.Wife" fetch="join" unique="true">
<column name="WIFE" />
</many-to-one>
</class>
</hibernate-mapping>
Wife.hbm.xml简要配置。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2011-10-2 22:15:15 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.akwolf.bean.Wife" table="WIFE">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
</class>
</hibernate-mapping>
Annotation双向必设mappedBy
3、双向主键
4、双向外键
现在在wife添加一个Husband的属性使其可以找到husband,则需在Wife.hbm.xml中进行配置
<hibernate-mapping>
<class name="com.akwolf.bean.Wife" table="WIFE">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<one-to-one name="husband" property-ref="wife"></one-to-one>
</class>
</hibernate-mapping>
对于property-ref="wife",就是指明要进行关联的属性已经在husband的wife属性进行关联了
从wife端查询husband时,hibernate生成的查询语句
Hibernate:
select
wife0_.ID as ID1_1_,
wife0_.NAME as NAME1_1_,
husband1_.ID as ID0_0_,
husband1_.NAME as NAME0_0_,
husband1_.AGE as AGE0_0_,
husband1_.WIFE as WIFE0_0_
from
WIFE wife0_
left outer join
HUSBAND husband1_
on wife0_.ID=husband1_.WIFE
where
wife0_.ID=?
三、一对多和多对一关系
1、外键一般放在多的一边
2、多对一单向关联,(Person:Phone)在Phone实体中保存Person的引用(常用)。
Person简略信息
private int id;
private int name;
Phone简略信息
private int id ;
private String name ;
private Person person ;
Person.hbm.xml配置
<hibernate-mapping>
<class name="com.akwolf.bean.Person" table="PERSON">
<id name="id" type="int">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="name" type="int">
<column name="NAME" />
</property>
</class>
</hibernate-mapping>
Phone.hbm.xml配置
<hibernate-mapping>
<class name="com.akwolf.bean.Phone" table="PHONE">
<id name="id" type="int">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<!-- 设置多对一单向关联 -->
<many-to-one name="person" class="com.akwolf.bean.Person" fetch="join">
<column name="PERSON" />
</many-to-one>
</class>
</hibernate-mapping>
3、一对多单向关联,即在Person中保存Phone的一个引用,一般通过Set集合实现。
Person:
private int id;
private int name;
private Set<Phone> phones = new HashSet<Phone>() ;
Phone:
private int id ;
private String name ;
Person.hbm.xml:
<hibernate-mapping>
<class name="com.akwolf.bean.Person" table="PERSON">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="int">
<column name="NAME" />
</property>
<set name="phones">
<!-- 表示在Phone端生成Person外键的字段名,关联还是放在多的一方(Phone) -->
<key column="personId"/>
<one-to-many class="com.akwolf.bean.Phone"/>
</set>
</class>
</hibernate-mapping>
Phone.hbm.xml
<hibernate-mapping>
<!-- 多这一方没有明确指明关联到一个Person,关系在Person中对象指明,在数据库中还是在Phone这端建立外键进行关联 -->
<class name="com.akwolf.bean.Phone" table="PHONE">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
</class>
</hibernate-mapping>
4、一对多或多对一双向关联(少用)
Person
private int id;
private int name;
private Set<Phone> phones = new HashSet<Phone>() ;
Phone
private int id;
private String name;
private Person person;
Person.hbm.xml
<hibernate-mapping>
<class name="com.akwolf.bean.Person" table="PERSON">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="int">
<column name="NAME" />
</property>
<set name="phones">
<!-- 表示在Phone端生成Person外键的字段名,关联还是放在多的一方(Phone) -->
<key column="personId"/>
<one-to-many class="com.akwolf.bean.Phone"/>
</set>
</class>
</hibernate-mapping>
Phone.hbm.xml
<hibernate-mapping>
<!-- 多这一方没有明确指明关联到一个Person,对象关系在
Person中指明,在数据库中还是在Phone这端建立外键进行关联
-->
<class name="com.akwolf.bean.Phone" table="PHONE">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<!-- 在Person中已经指明关联关系,现在让Phone的外键与Person中指定为同一个即可(同名) -->
<many-to-one name="person" column="personId"></many-to-one>
</class>
</hibernate-mapping>
或Person.hbm.xml
<hibernate-mapping>
<class name="com.akwolf.bean.Person" table="PERSON">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="int">
<column name="NAME" />
</property>
<!-- 表示字段名由对方进行控制 -->
<set name="phones" inverse="true">
<key/>
<one-to-many class="com.akwolf.bean.Phone"/>
</set>
</class>
</hibernate-mapping>
四、多对多关系
1、多对多单向关联。
一个系统中用户和角色是多对多关系,即一个用户(User)可以是多个角色(Role),一个Role也可以被多个User所持有。
User:
private int id;
private String name;
private Set<Role> roles = new HashSet<Role>();
Role:
private int id;
private String description;
Role.hbm.xml:
<hibernate-mapping>
<class name="com.akwolf.bean.Role" table="ROLE">
<id name="id" type="int">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" />
</property>
</class>
</hibernate-mapping>
User.hbm.xml中描述建立中间表,并建立User到Role的关联
<hibernate-mapping>
<class name="com.akwolf.bean.User" table="USER">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<!-- table属性用于指定生成中间表的名称 -->
<set name="roles" table="user_role">
<!-- 当前映射实体在中间表中的字段名 -->
<key column="userId"/>
<!-- 指定另一个被映射的实体,及其在中间表中的字段名 -->
<many-to-many column="roleId" class="com.akwolf.bean.Role"/>
</set>
</class>
</hibernate-mapping>
2、多对多双向(少用)
现在要使Role和User双向关联,双向的*.hbm.xml都要设置Many-to-many,对Role变动一下
private int id;
private String description;
private Set<User> users = new HashSet<User>();
对Role.hbm.xml进行下列配置
<hibernate-mapping>
<class name="com.akwolf.bean.Role" table="ROLE">
<id name="id" type="int">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" />
</property>
<!-- inverse="true"表明已经有一个实体在管理中间,自己不用在去管理中间表 -->
<set name="users" table="user_role" inverse="true">
<!-- 当前实体在中间表中字段 -->
<key column="roleId"/>
<!-- 指定另一端实体在和在中间表中的字段名 -->
<many-to-many column="userId" class="com.akwolf.bean.User"/>
</set>
</class>
</hibernate-mapping>