原文:http://www.cnblogs.com/huxi/archive/2009/12/15/1624988.html

以简单的两个类为例: 
User(int id, String name) 
Group(int id, String name)

没有关联关系时的关系模型: 
t_user(id int pk, name varchar) 
t_group(id int pk, name varchar)

一、多对一和一对多关联映射(多个用户有相同的组)

这几种关联映射后的关系模型是相同的: 
t_user(id int pk, name varchar, gid int fk->t_group(id)
t_group(id int pk, name varchar)

1、多对一单向关联

实体模型: 
bean.User(int id, String name, Group group
bean.Group(int id, String name)

1
2
3
4
5
6
7
8
9
10
<!-- bean/User.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<many-to-one>映射多对一关系。导出ddl时将自动生成一个外键 -->
        <many-to-one name="group" column="gid"/>
    </class>
</hibernate-mapping>
1
2
3
4
5
6
7
8
<!-- bean/Group.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
    </class>
</hibernate-mapping>
2、一对多单向关联(几乎不用)

实体模型: 
bean.User(int id, String name) 
bean.Group(int id, String name, Set users)

1
2
3
4
5
6
7
8
<!-- bean/User.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
    </class>
</hibernate-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- bean/Group.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<set>映射集合 -->
        <set name="users">
            <!-- 使用<key>指定引用至自身的外键表(t_user)中的外键 -->
            <key column="gid"/>
            <!-- 使用<one-to-many>映射一对多关系 -->
            <one-to-many class="bean.User"/>
        </set>
    </class>
</hibernate-mapping>

为Group加入集合也可以使用List(<list>),注意不能指定类型是具体的HashSet或ArrayList,只能是接口Set或List。 
集合标签可以使用order-by属性指定排序:

1
<set name="users" order-by="id desc">
3、双向关联

实体模型: 
bean.User(int id, String name, Group group
bean.Group(int id, String name, Set users)

1
2
3
4
5
6
7
8
9
10
<!-- bean/User.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<many-to-one>映射多对一关系。导出ddl时将自动生成一个外键 -->
        <many-to-one name="group" column="gid"/>
    </class>
</hibernate-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- bean/Group.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<set>映射集合 -->
        <set name="users">
            <!-- 使用<key>指定引用至自身的外键表(t_user)中的外键 -->
            <key column="gid"/>
            <!-- 使用<one-to-many>映射一对多关系 -->
            <one-to-many class="bean.User"/>
        </set>
    </class>
</hibernate-mapping>

双向关联中,为<set>加入”inverse=true”可以反转维护关系:Hibernate将放弃从一的一端维护。意思就是user和group的关系必须使用user维护,操作group时Hibernate将不维护这个关系。

1
<set name="users" inverse="true">

操作group的示例:

1
2
3
4
5
6
7
8
9
10
11
12
session.beginTransaction();
User user = new User();
user.setName("张三");
 
Group group = new Group();
group.setName("admin");
group.setUsers(new HashSet());
group.getUsers().add(user);
 
session.save(user);
session.save(group);
session.getTransaction().commit();

没有配置inverse=”true”时,Hibernate输出了添加user和group,并更新user的语句:

Hibernate: insert into t_user (name, gid) values (?, ?)
Hibernate: insert into t_group (name) values (?)
Hibernate: update t_user set gid=? where id=?
而配置了inverse=”true”后,Hibernate仅仅输出了添加user和group的语句,并没有更新user,放弃了关系的维护:
Hibernate: insert into t_user (name, gid) values (?, ?)
Hibernate: insert into t_group (name) values (?)
此时应该从user端维护关系:
1
2
3
4
5
6
7
8
9
10
11
session.beginTransaction();
Group group = new Group();
group.setName("admin");
 
User user = new User();
user.setName("张三");
user.setGroup(group);
 
session.save(group);
session.save(user);
session.getTransaction().commit();

因为外键列在t_user表中,从group端维护需要操作多表,所以从user端维护关系更加合理,效率也更高。上面的代码输出两条SQL语句,插入数据的同时也维护了关系:

Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_user (name, gid) values (?, ?)

二、一对一关联映射(每个用户独有一个组)

依照映射方法不同,可分为主键关联映射唯一外键关联映射。主键关联是维护两张表的主键一致,如有必要还可以在主键上再加上外键约束;唯一外键关联则类似于多对一关联,为表加入一个外键列,不过一对一关联会同时将这个外键加上唯一约束。

1、主键关联映射

主键关联生成的关系模型: 
t_user(id int pk fk->t_group(id), name varchar) 
t_group(id int pk, name varchar)

1.1、主键单向关联

实体模型: 
bean.User(int id, String name, Group group
bean.Group(int id, String name)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- bean/User.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <!-- 指定主键生成策略为外键 -->
            <generator class="foreign">
                <!-- 指定要参照的属性 -->
                <param name="property">group</param>
            </generator>
        </id>
        <property name="name"/>
        <!-- 使用<one-to-one>映射一对一关系。 -->
        <one-to-one name="group">
    </class>
</hibernate-mapping>
1
2
3
4
5
6
7
8
<!-- bean/Group.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
    </class>
</hibernate-mapping>

主键关联由Hibernate维护,不依赖数据库。如果需要在数据库端也生成外键约束,可以使用constrained:

1
<one-to-one name="group" constrained="true"/>

1.2、主键双向关联

实体模型: 
bean.User(int id, String name, Group group
bean.Group(int id, String name, User user)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- bean/User.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <!-- 指定主键生成策略为外键 -->
            <generator class="foreign">
                <!-- 指定要参照的属性 -->
                <param name="property">group</param>
            </generator>
        </id>
        <property name="name"/>
        <!-- 使用<one-to-one>映射一对一关系。 -->
        <one-to-one name="group">
    </class>
</hibernate-mapping>
1
2
3
4
5
6
7
8
9
10
<!-- bean/Group.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<one-to-one>映射一对一关系 -->
        <one-to-one name="user"/>
    </class>
</hibernate-mapping>
2、唯一外键关联映射

唯一外键关联生成的关系模型: 
t_user(id int pk, name varchar, gid int fk->t_group(id)
t_group(id int pk, name varchar)

2.1、唯一外键单向关联

实体模型: 
bean.User(int id, String name, Group group
bean.Group(int id, String name)

1
2
3
4
5
6
7
8
9
10
11
12
<!-- bean/User.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <!-- 为<many-to-one>加上unique就变成了一对一 -->
        <many-to-one name="group" unique="true" column="gid"/>
    </class>
</hibernate-mapping>
1
2
3
4
5
6
7
8
<!-- bean/Group.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
    </class>
</hibernate-mapping>

2.2、唯一外键双向关联

实体模型: 
bean.User(int id, String name, Group group
bean.Group(int id, String name, User user)

1
2
3
4
5
6
7
8
9
10
11
12
<!-- bean/User.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <!-- 为<many-to-one>加上unique就变成了一对一 -->
        <many-to-one name="group" unique="true" column="gid"/>
    </class>
</hibernate-mapping>
1
2
3
4
5
6
7
8
9
10
<!-- bean/Group.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
        <!-- 使用<one-to-one>映射一对一 -->
        <one-to-one name="user"/>
    </class>
</hibernate-mapping>

三、多对多关联映射(每个用户拥有多个组,每个组也有多个用户)

多对多关联映射关系使用中间表表示。导出关系模型时Hibernate将自动生成复合主键以及外键约束。

关系模型: 
t_user(id int pk, name varchar) 
t_group(id int pk, name varchar) 
t_user_group(userid int fk->t_user(id), groupid int fk->t_group(id)pk(userid, groupid))

1、多对多单向关联

实体模型: 
bean.User(int id, String name, Set groups
bean.Group(int id, String name)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- bean/User.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <!-- 使用<set>映射集合,在多对多关系中,Hibernate将生成第三张表 -->
        <set name="groups" table="t_user_group">
            <!-- 使用<key>指定引用至自身的外键表(t_user_group)中的外键 -->
            <key column="userid"/>
            <!-- 使用<many-to-many>映射多对多关系,column指定另一端在表t_user_group中的列 -->
            <many-to-many class="bean.Group" column="groupid"/>
        </set>
    </class>
</hibernate-mapping>
1
2
3
4
5
6
7
8
<!-- bean/Group.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id"><generator class="native"/></id>
        <property name="name"/>
    </class>
</hibernate-mapping>
1、多对多单向关联

实体模型: 
bean.User(int id, String name, Set groups
bean.Group(int id, String name, Set users)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- bean/User.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.User" table="t_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <!-- 使用<set>映射集合,在多对多关系中,Hibernate将生成第三张表 -->
        <set name="groups" table="t_user_group">
            <!-- 使用<key>指定引用至自身的外键表(t_user_group)中的外键 -->
            <key column="userid"/>
            <!-- 使用<many-to-many>映射多对多关系,column指定另一端在表t_user_group中的列 -->
            <many-to-many class="bean.Group" column="groupid"/>
        </set>
    </class>
</hibernate-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- bean/Group.hbm.xml -->
 
<hibernate-mapping>
    <class name="bean.Group" table="t_group">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <!-- 使用<set>映射集合,在多对多关系中,Hibernate将生成第三张表 -->
        <set name="users" table="t_user_group">
            <!-- 使用<key>指定引用至自身的外键表(t_user_group)中的外键 -->
            <key column="group"/>
            <!-- 使用<many-to-many>映射多对多关系,column指定另一端在表t_user_group中的列 -->
            <many-to-many class="bean.User" column="userid"/>
        </set>
    </class>
</hibernate-mapping>

多对多的双向关联同样可以在不想要维护关系的一端的<set>里设置inverse=”true”;但是必须有一端可以维护,也就是说只可以设置一个。

Hibernate关联映射(转载)的更多相关文章

  1. Hibernate关联映射(一对多/多对多)

    版权声明:翀版 https://blog.csdn.net/biggerchong/article/details/843401053.  Hibernate关联映射上接Hibernate持久化类:h ...

  2. Hibernate关联映射关系

    Hibernate关联映射关系 一.双向一对多关联映射关系:当类与类之间建立了关联,就可以方便的从一个对象导航到另一个或另一组与它关联的对象(一对多双向关联和多对一双向关联是完全一样的) 1.1创建实 ...

  3. Oracle primary,unique,foreign 区别,Hibernate 关联映射

    Oracle primary,unique,foreign 区别 转:http://www.cnblogs.com/henw/archive/2012/08/15/2639510.html NOT N ...

  4. 第六章 Hibernate关联映射

    第六章 hibernate关联映射一.本章知识点分为2部分:1.关联关系:单向多对一关联关系,双向一对多关联关系(含一对多关联关系),多对多关联关系2.延迟加载:类级别加载策略,一对多加载策略,多对一 ...

  5. 【学习笔记】Hibernate关联映射(Y2-1-6)

    Hibernate关联映射 关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用. 1.单向多对一关联 准备数据库 部门表和员工表 其中部门表有两列 部门编号和名称 员工表有三列 员工 ...

  6. 第三章Hibernate关联映射

    第三章Hibernate关联映射 一.关联关系 类与类之间最普通的关系就是关联关系,而且关联是有方向的. 以部门和员工为列,一个部门下有多个员工,而一个员工只能属于一个部门,从员工到部门就是多对一关联 ...

  7. (转)Hibernate关联映射——对象的三种关系

    http://blog.csdn.net/yerenyuan_pku/article/details/70148618 Hibernate关联映射——对象的三种关系 Hibernate框架基于ORM设 ...

  8. (转)Hibernate关联映射——一对多(多对一)

    http://blog.csdn.net/yerenyuan_pku/article/details/70152173 Hibernate关联映射——一对多(多对一) 我们以客户(Customer)与 ...

  9. Java三大框架之——Hibernate关联映射与级联操作

    什么是Hibernate中的关联映射? 简单来说Hibernate是ORM映射的持久层框架,全称是(Object Relational Mapping),即对象关系映射. 它将数据库中的表映射成对应的 ...

随机推荐

  1. console.log的应用

    这两天在学javascript,但是有个问题老是觉得很疑惑,那就是这两个表达式到底有啥区别,虽然结果输出都差不多,但是我想这个两个表达式被开发出来,肯定是有意义的吧!哪位高手解答下吧!Thanks i ...

  2. SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT 'OpenRowset/OpenDatasource' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'Ad Hoc Distributed Queries'。

    今天单位一ASP.NET网站,里面有个功能是导出数据,发现一导出就报错,报错内容是:SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT ...

  3. Python_sklearn机器学习库学习笔记(一)_一元回归

    一.引入相关库 %matplotlib inline import matplotlib.pyplot as plt from matplotlib.font_manager import FontP ...

  4. Ubuntu 14.04下搭建Python3.4 + PyQt5.3.2 + Eric6.0开发平台

    引言 找了很多Python GUI工具集,还是觉得PyQt比较理想,功能强大跨平台,还支持界面设计器.花一天时间折腾了Ubuntu14.04(32位)+ Python3.4 + Qt5.3.2 + P ...

  5. Angular.js参考

    http://www.cnblogs.com/popo123/p/5673955.html

  6. CentOS7搭建NAS,包括NFS、ISCSI

    第一步:安装 更新系统 yum update 安装iftop yum install epel-release yum install iftop 安装NFS yum install nfs-util ...

  7. JavaScript parseInt() toString()函数

    parseInt(string, radix) string:必需.要被解析的字符串 radix:可选.表示要解析的数字的基数.该值介于 2 ~ 36 之间. 如果省略该参数或其值为 0,则数字将以 ...

  8. Win8 x64环境下VS2010 C#工程运行报错:没有注册类 (异常来自 HRESULT:0x80040154

    来源:http://blog.sina.com.cn/s/blog_7095482001019c2v.html 问题描述: 在Win8 x64环境下,VS2010的C#工程中引用了COM组件(Acti ...

  9. Win7 64位 VS2013环境编译boost1_58_0

    备忘,发现好多不常用的东西不记笔记再想用要重新花时间找,所以试着开始记笔记,写入博客吧. 首先去官网下最新的版本 http://www.boost.org/ 写本文时boost最新版本为1_58_0, ...

  10. java内部类和匿名内部类

    内部类即是包含在类里面的又一个类. java内部类分为: 成员内部类.静态嵌套类.方法内部类.匿名内部类 . 内部类的共性 (1).内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.clas ...