Hibernate 关联关系学习笔记


一、总体来分有一对一、一对多、多对一、多对多这四种关系。

二、一对一关系

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>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值