Hibernate入门(5):关联映射&继承映射
来源:互联网 发布:xp取消网络凭证 编辑:程序博客网 时间:2024/06/13 00:29
关联映射
1、除了关系型数据库本身提供的基于关系的关联映射,Hibernate 也提供了面向对象的关联映射支持,这些关联关系大大简化了持久层数据的访问;
2、Hibernate提供的关联关系可以分为以下2种,可以根据需求选择关联形式;
单向关联:只能从一端访问另一端;双向关联:两端都可以相互访问;
3、单向关联包含以下4种关系:
1-1(一对一),1-N(一对多),N-1(多对一),N-N(多对多);
4、双向关联包含以下3种关系(双向关联中1-N,N-1完全相同):
1-1,1-N,N-N;
5、对于这些关联关系,hibernate 提供了以下4个注解支持:
@OneToOne:1-1关系
@OneToMore:1-N关系
@MoreToOne:N-1关系
@MoreToMore:N-N关系
这些注解支持的常用属性如下:
6、对于1-N 关联关系,在数据库建模角度来讲,这两个关联的表存在基于外键分别为主表、从表的约束关系,hibernate有2种方式来进行表示:
①组件映射:将从表记录映射为持久化类的组件,参见04. Hibernate 集合映射&组件映射,这种方式下 Hibernate 默认启用级联操作,组件的声明周期依赖于父对象:父对象保存时,组件被保存,父对象被删除时,组件被删除;
②关联映射:将从表记录映射为持久化实体,这种方式下 hibernate 默认不开启级联操作,从表实体的拥有自己的声明周期,从而允许其他实体共享对其的引用;
7、Hibernate 支持有连接表和无连接表的关联映射;
无连接表时,需要使用 @JoinColumn ,来映射外键列,支持属性如下:
有连接表时,需要使用 @JoinTable,来映射底层连接表的信息,支持属性如下:
单向 N-1 关联
1)无连接表的单向 N-1关联
示例使用数据表,多个person可能拥有同一个address;
Person.java
1
import javax.persistence.*;
2
3
4
name="persion") (
5
public class Person {
6
name="person_id") (
7
private int id;
8
name="persion_name") (
9
private String name;
10
11
//定义Persion实体关联的Address实体
12
targetEntity = Address.class,cascade = CascadeType.ALL) //N-1关联,启用所有级联操作 (
13
name="address_id",referencedColumnName="address_id" ,nullable = false) //映射外键列 (
14
private Address address;
15
16
//省略所有getter,setter方法
17
}
18
address.java
1
import javax.persistence.*;
2
3
4
name="address") (
5
public class Address {
6
name="address_id") (
7
private int id;
8
name="addrrss_detail") (
9
private String detial;
10
11
//省略所有 getter,setter方法
12
13
}
2)有关联表的单向 N-1关联
示例数据表如下:
Person.java
1
import javax.persistence.*;
2
3
name="person") (
4
public class Persion {
5
name="person_id") (
6
private int id;
7
name="person_name") (
8
private String name;
9
10
//定义Persion实体关联的Address实体
11
targetEntity = Address.class,cascade = CascadeType.ALL) //N-1关联,启用所有级联操作 (
12
//映射连接表
13
name="person_address", //指定连接表名称 (
14
joinColumns = (name="person_id",referencedColumnName = "person_id",unique=true), //连接表外键对当前实体主键的参照
15
inverseJoinColumns = (name="address_id",referencedColumnName = "address_id")) //连接表外键对关联实体主键的参照
16
private Address address;
17
18
//省略所有getter,setter方法
19
}
address.java 同上
单向 1-N 关联
对于 1-N 关联,Hibernate 推荐使用双向关联,同时不让1的一端控制关联关系,而使用N的一端控制关联关系,当程序不得不使用使用单向的 1-N,优先采用连接表的 1-N 关联;
单向 1-1 关联
单向 1-1 关联一般使用的是无连接表的映射方式;
Person.java
1
import javax.persistence.*;
2
3
4
name="person") (
5
public class Persion {
6
name="person_id") (
7
private int id;
8
name="person_name") (
9
private String name;
10
11
//定义Persion实体关联的Address实体
12
targetEntity = Address.class,cascade = CascadeType.ALL) //1-1关联,启用所有级联操作 (
13
name="address_id",referencedColumnName="address_id" ,nullable = false, unique = true) //映射外键列 (
14
private Address address;
15
16
//省略所有getter,setter方法
17
}
单向 N-N 关联
单向 N-N 关联的代码和 单向 1-N 的代码几乎完全相同,控制关系的一端只需要增加一个Set类型的属性即可;
一般 N-N 关联使用连接表的形式进行关联;
Person.java
1
2
name="person") (
3
public class Persion {
4
name="person_id") (
5
private int id;
6
name="person_name") (
7
private String name;
8
9
//定义Persion实体关联的Address实体
10
targetEntity = Address.class,cascade = CascadeType.ALL) //N-N关联,启用所有级联操作 (
11
//映射连接表
12
name="person_address", //指定连接表名称 (
13
joinColumns = (name="person_id",referencedColumnName = "person_id"), //连接表外键对当前实体主键的参照
14
inverseJoinColumns = (name="address_id",referencedColumnName = "address_id")) //连接表外键对关联实体主键的参照
15
private Set<Address> addresses = new HashSet<>();
16
17
//省略所有getter,setter方法
18
}
双向 1-N 关联
大部分时候,双向 1-N 关联使用无连接表的形式进行映射即可;
1)无连接表的双向 1-N 关联
Person.java
1
2
name="person") (
3
public class Person {
4
name="person_id") (
5
private int id;
6
name="person_name") (
7
private String name;
8
9
targetEntity = Address.class,cascade = CascadeType.ALL,mappedBy = "person") //1-N关联,取消本实体的关联控制 (
10
private Set<Address> addresses = new HashSet<>();
11
12
//省略所有getter,setter方法
13
}
14
Address.java
1
2
name="address") (
3
public class Address {
4
name="address_id") (
5
private int id;
6
name="addrrss_detail") (
7
private String detial;
8
9
targetEntity = Person.class,cascade=CascadeType.ALL) (
10
name="person_id",referencedColumnName = "person_id",nullable = false) (
11
private Person person;
12
13
//省略所有 getter,setter方法
14
15
}
2)有连接表的双向 1-N 关联
Persion.java
1
2
name="person") (
3
public class Person {
4
name="person_id") (
5
private int id;
6
name="person_name") (
7
private String name;
8
9
targetEntity = Address.class,cascade = CascadeType.ALL,mappedBy = "person") //1-N关联,取消本实体的关联控制 (
10
private Set<Address> addresses = new HashSet<>();
11
//省略所有getter,setter方法
12
}
13
Address.java
1
2
name="address") (
3
public class Address {
4
name="address_id") (
5
private int id;
6
name="addrrss_detail") (
7
private String detial;
8
9
targetEntity = Person.class,cascade=CascadeType.ALL) (
10
name="person_address", (
11
joinColumns = (name="adddress_id",referencedColumnName = "address_id",unique=true),
12
inverseJoinColumns = (name="person_id",referencedColumnName = "person_id"))
13
private Person person;
14
15
//省略所有 getter,setter方法
16
17
}
双向 1-1 关联
双向 1-1 关联一般使用无连接表的形式进行映射
Person.java
1
2
name="person") (
3
public class Person {
4
name="person_id") (
5
private int id;
6
name="person_name") (
7
private String name;
8
9
targetEntity = Address.class,cascade = CascadeType.ALL,mappedBy="person") //1-N关联,取消本实体的关联控制 (
10
private Address address;
11
//省略所有getter,setter方法
12
}
13
address.java
1
2
name="address") (
3
public class Address {
4
name="address_id") (
5
private int id;
6
name="addrrss_detail") (
7
private String detial;
8
9
targetEntity = Person.class,cascade=CascadeType.ALL) (
10
name="person_id",referencedColumnName = "person_id",unique=true) (
11
private Person person;
12
13
//省略所有 getter,setter方法
14
15
}
双向 N-N 关联
一般双向N-N关联,使用连接表的形式映射;
Person.java
1
2
name="person") (
3
public class Person {
4
name="person_id") (
5
private int id;
6
name="person_name") (
7
private String name;
8
9
targetEntity = Address.class,cascade = CascadeType.ALL) (
10
name="person_address", (
11
joinColumns = (name="person_id",referencedColumnName = "person_id"),
12
inverseJoinColumns = (name="address_id",referencedColumnName = "address_id"))
13
private Set<Address> addresses = new HashSet<>();
14
//省略所有getter,setter方法
15
}
Address.java
1
2
name="address") (
3
public class Address {
4
name="address_id") (
5
private int id;
6
name="addrrss_detail") (
7
private String detial;
8
9
targetEntity = Person.class,cascade=CascadeType.ALL) (
10
name="person_address", (
11
joinColumns = (name="adddress_id",referencedColumnName = "address_id"),
12
inverseJoinColumns = (name="person_id",referencedColumnName = "person_id"))
13
private Set<Person> persons = new HashSet<>();
14
//省略所有 getter,setter方法
15
16
}
继承映射
hibernate 支持将继承层次结构与数据表进行映射,其定义了3种继承映射的策略:
① 每个类层次对应一张表的映射策略;
② 每个具体类对应一张表的映射策略;
③ 连接子类的映射策略;
以下使用图示的继承层次进行示例说明:
每个类层次对应一张表的映射策略
这是Hibernate默认的继承映射策略,在这种策略下,整个继承层次结构都储存在一张表中,如上继承层次中 Employee,Regular_Emplee,Constract_Employee 3个实体都储存在同一张表中;
使用这种策略时,Hibernate 会为该表额外创建一列,该列用于区分每行记录为哪一个类的实例,该列为辨别者列(discriminiator),使用@DiscriminatorColumn配置辨别者列,
Employee.java
1
2
name = "employee") (
3
strategy=InheritanceType.SINGLE_TABLE) //标注继承方式为单表方式 (
4
name="type",discriminatorType=DiscriminatorType.STRING) //指定辨别者列的数据类型 (
5
value="employee") //指定该实体的辨别者列值 (
6
public class Employee {
7
8
strategy = GenerationType.AUTO) (
9
name = "id") (
10
private int id;
11
12
name = "name") (
13
private String name;
14
15
// setters and getters
16
}
Regular_Employee.java
1
2
"regularemployee") (
3
public class Regular_Employee extends Employee {
4
5
name = "salary") (
6
private float salary;
7
8
name = "bonus") (
9
private int bonus;
10
11
// setters and getters
12
}
Contract_Employee.java
1
2
"contractemployee") (
3
public class Contract_Employee extends Employee {
4
5
name = "pay_per_hour") (
6
private float pay_per_hour;
7
8
name = "contract_duration") (
9
private String contract_duration;
10
11
// setters and getters
12
}
每个具体类对应一张表的映射策略
这一种策略为每一个具体类对应一个具体的数据表,一般不会使用这种策略,因为有可能会导致数据过渡冗余;
Employee.java
1
2
name = "employee") (
3
strategy = InheritanceType.TABLE_PER_CLASS) (
4
public class Employee {
5
6
strategy = GenerationType.AUTO) (
7
name = "id") (
8
private int id;
9
10
name = "name") (
11
private String name;
12
13
// setters and getters
14
15
}
Regular_Employee.java
1
2
name = "regularemployee") (
3
({
4
name = "id", column = (name = "id")), (
5
name = "name", column = (name = "name")) }) (
6
public class Regular_Employee extends Employee {
7
8
name = "salary") (
9
private float salary;
10
11
name = "bonus") (
12
private int bonus;
13
14
// setters and getters
15
16
}
Contract_Employee.java
1
2
name = "contractemployee") (
3
({
4
name = "id", column = (name = "id")), (
5
name = "name", column = (name = "name")) }) (
6
public class Contract_Employee extends Employee {
7
8
name = "pay_per_hour") (
9
private float pay_per_hour;
10
11
name = "contract_duration") (
12
private String contract_duration;
13
14
// setters and getters
15
}
连接子类的映射策略
采用这种映射策略时,父类的实体保存在父类表里,而子类的实体则由父类表和子类表共同储存,即将子类和父类共同的属性存储在父类表中;
Employee.java
1
2
name = "employee") (
3
strategy = InheritanceType.JOINED) (
4
public class Employee {
5
6
strategy = GenerationType.AUTO) (
7
name = "id") (
8
private int id;
9
10
name = "name") (
11
private String name;
12
13
// setters and getters
14
}
Regular_Employee.java
1
2
name = "regularemployee") (
3
name = "id") (
4
public class Regular_Employee extends Employee {
5
name = "salary") (
6
private float salary;
7
8
name = "bonus") (
9
private int bonus;
10
11
// setters and getters
12
}
Contract_Employee.java
1
2
name = "contractemployee") (
3
name = "id") (
4
public class Contract_Employee extends Employee {
5
6
name = "pay_per_hour") (
7
private float pay_per_hour;
8
9
name = "contract_duration") (
10
private String contract_duration;
11
12
// setters and getters
13
14
}
阅读全文
0 0
- Hibernate入门(5):关联映射&继承映射
- Hibernate 、继承关联映射
- 【hibernate】关联映射那些事(四)----继承映射
- Hibernate关联关系映射之继承映射
- hibernate中的关联映射图解 ---- 继承映射
- 【Hibernate】--关联关系映射:继承映射
- Hibernate关联映射(5)
- 关联映射(hibernate映射)
- Hibernate继承映射简单入门
- Hibernate多对多关联映射和继承映射
- Hibernate学习手记(5)--关联映射
- Hibernate映射详解(六)--继承映射
- Hibernate关联映射(转)
- Hibernate的映射(关联)
- hibernate 关联映射(2)
- Hibernate关联映射(1)
- Hibernate映射关联(2)
- Hibernate集合映射、关联映射
- C语言模块化程序设计
- github代码资源
- 广州CVTE公司笔试程序题
- openstack mtu (by quqi99)
- 设计模式 3-23 抽象工厂模式
- Hibernate入门(5):关联映射&继承映射
- QToolBox
- 【转】Java中创建对象的5种方式
- Gensim官方介绍翻译(一)
- node.js原始路径配置
- 单调队列优化多重背包(含构造问题<POJ 1742 coin>)
- C# 委托简介
- 09.07周四
- 缓存那些事
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
氯化锡
锡价走势图
废锡丝
废锡多少钱一吨
无铅低温锡丝
锡制品
锡岩仙洞
回收锡块
锡焊机
锡酸锌
回收锡多少钱一斤
锡铅合金
回收锡丝
锡渣抗氧化还原剂
自动锡机
锡酒壶
烙铁头不沾锡
锡制工艺品价格
收购锡条
锡价格行情
不锈钢锡丝
锡回收价格
含银锡价格
6337锡丝
锡茶壶
锡丝品牌
锡磷青铜
锡锅
氟化亚锡
含银锡线
锡焊料
锡有毒吗
纯锡茶叶罐多少钱
中实锡丝
锡业
金属锡价格
无卤锡线
高价回收锡条
锡渣还原
锡渣收购价格
柠檬酸亚锡二钠