文档章节

@OneToMany、@ManyToOne以及@ManyToMany讲解

gxchan
 gxchan
发布于 2015/12/23 16:14
字数 1017
阅读 423
收藏 6

一、一对多(@OneToMany)
1、单向一对多模型
假设通过一个客户实体可以获得多个地址信息。
对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。
(1) 映射策略---外键关联
在数据库中表customer和表结构address定义,如下:

create table customer (
  id int(20) not null auto_increment,
  name varchar(100),
  primary key(id)
)
 
create table address (
  id int(20) not null auto_increment,
  province varchar(50),
  city varchar(50),
  postcode varchar(50),
  detail varchar(50),
  customer_id int(20),
  primary key (id)
)


注意此时外键定义在多的一方,也就是address表中。

 此时,表customer映射为实体CustomerEO,代码如下:

@Entity
@Table (name="customer")
public class CustomerEO implements java.io.Serializable {
  @OneToMany(cascade={ CascadeType.ALL })
  @JoinColumn(name="customer_id")
  private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
 ...
}

注释@OneToMany的定义代码如下: 

@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToMany {
  Class targetEntity() default void.class;
  CascadeType[] cascade() default {};
  FetchType fetch() default LAZY;
  String mappedBy() default "";
}

使用时要注意一下几点问题: 

a、targetEntity属性表示默认关联的实体类型。如果集合类中指定了具体类型了,不需要使用targetEntity.否则要指定targetEntity=AddressEO.class。 
b、mappedBy属性用于标记当实体之间是双向时使用。 

(2) 映射策略---表关联 
在上面address表中去掉customer_id字段,在增加一个表ref_customer_address,如下: 

--客户地址关系表
create table ref_customer_address (
  customer_id int(20) not null,
  address_id int(20) not null unique
)

此时表customer映射为CustomerEO实体,代码如下: 

@Entity
@Table(name = "customer")
public class CustomerEO implements java.io.Serializable {
  ...
  @OneToMany(cascade = { CascadeType.ALL })
  @JoinTable(name="ref_customer_address",
           joinColumns={ @JoinColumn(name="customer_id",referencedColumnName="id")},
           inverseJoinColumns={@JoinColumn(name="address_id",referencedColumnName="id")})
  private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
  ...
}

表关联@JoinTable,定义如下: 

@Target({METHOD,FIELD}) 
public @interface JoinTable {
  String name() default "";
  String catalog() default "";
  String schema() default "";
  JoinColumn[] joinColumns() default {};
  JoinColumn[] inverseJoinColumns() default {};
  UniqueConstraint[] uniqueConstraints default {};
}

其中:
a、该标记和@Table相似,用于标注用于关联的表。
b、name属性为连接两张表的表名。默认的表名为:“表名1”+“-”+“表名2”,上面例子默认的表名为customer_address。
c、joinColumns属性表示,在保存关系中的表中,所保存关联的外键字段。
d、inverseJoinColumns属性与joinColumns属性类似,不过它保存的是保存关系的另一个外键字段。

(3) 默认关联
在数据库底层为两张表添加约束,如下:

create table customer_address (
  customer_id int(20) not null,
  address_id int(20) not null unique
)
alter table customer_address add constraint fk_ref_customer foreign key (customer_id) references customer (id);
 
alter table customer_address add constraint fk_ref_address foreign key (address_id) references address (id);

这样,在CustomerEO中只需要在标注@OneToMany即可!


二、多对一@ManyToOne
1、单向多对一模型。
(1) 外键关联
配置AddressEO实体如下:

@Entity
@Table(name="address")
public class AddressEO implements java.io.Serializable {
     
  @ManyToOne(cascade = { CascadeType.ALL })
  @JoinColumn(name="customer_id")
  private CustomerEO customer;
     
  // ...
}

@ManyToOne定义如下:

@Target({METHOD,FIELD}) @Retention(RUNTIME)
public @interface ManyToOne {
  Class targetEntity() default void.class;
  CascadeType[] cascade() default {};
  FetchType fatch() default EAGER;
  boolean optional() default true;
}

(2) 默认关联
数据库脚本定义的相关字段的约束,创建外键后,直接使用@ManyToOne

三、高级一对多和多对一映射
即双向关联模型,确定了双向关联后,多的一方AddressEO不变使用@ManyToOne,而CustomerEO实体修改为:

@Entity
@Table(name="customer")
public class CustomerEO {
     
  @OneToMany(mappedBy="customer")
  private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
     
  // ...
}

其中,@OneToMany标记中的mappedBy属性的值为AddressEO实体中所引用的CustomerEO实体的属性名。 

四、多对多(@ManyToMany)
和一对多类型,不在赘述。@ManyToMany标记的定义如下:

@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToMany {
  Class targetEntity() default void.class;
  CascadeType[] cascade() default {};
  FetchType fecth() default LAZY;
  String mappedBy() default "";
}

五、最后,谈谈关于集合类的选择
在映射关系中可以使用的集合类有Collection、Set、List和Map,下面看下如何选择。
1、定义时使用接口,初始化使用具体的类。
如Collection可以初始化为ArrayList或HashSet;
Set可以初始化为HashSet;
List可以初始化为ArrayList;
Map可以初始化为HashMap.
2、集合类的选择
Collection类是Set和List的父类,在未确定使用Set或List时可使用;
Set集合中对象不能重复,并且是无序的;
List集合中的对象可以有重复,并且可以有排序;
Map集合是带有key和value值的集合。


本文转载自:http://my.oschina.net/liangbo/blog/92301?fromerr=L70fKOfR

gxchan
粉丝 2
博文 6
码字总数 1934
作品 0
广州
高级程序员
私信 提问
@OneToMany、@ManyToOne以及@ManyToMany讲解(五)

一、一对多(@OneToMany) 1、单向一对多模型 假设通过一个客户实体可以获得多个地址信息。 对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。 (1) 映射策略---外键...

半夏alvin
2012/11/27
47K
2
Hibernate自动生成实体类注解

(2)、FetchType.EAGER:急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载。(3)、比方User类有两个属性,name跟address,就像百度知道,登录后用户名是需要显示出来的,此属性用...

MLeo
2012/11/13
8.3K
2
在model实体类中Hibernate的注释解释

Hibernate注解 1。@Entity(name="EntityName") 必须,name为可选,对应数据库中一的个表 2、@Table(name="",catalog="",schema="") 可选,通常和@Entity配合使用,只能标注在实体的class定义处,......

许大白
2013/04/08
103
0
Hibernate 实体类注解

Hibernate注解 1。@Entity(name="EntityName") 必须,name为可选,对应数据库中一的个表 2、@Table(name="",catalog="",schema="") 可选,通常和@Entity配合使用,只能标注在实体的class定义处,......

java-苦苦甜甜
2012/10/19
506
0
Hibernate几个基础问题

1、Hibernate的注解解释工具类: AnnotationBinder,hibernate的注解解释器是在hibernate初始化元数据信息的时候调用AnnotationBinder来完成注解的解释调用的。 2、使用Hibernate的OneToMany...

器石_
05/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx学习之模块

1、 stub_status模块: 用于展示nginx处理连接时的状态。 配置语法如下: Syntax:stub_status;Default:默认没有配置Context:server、location 可以编辑default.conf,加上如下配置: ...

码农实战
46分钟前
4
0
MySQL,必须掌握的6个知识点

目录 一、索引B+ Tree 原理 MySQL 索引 索引优化 索引的优点 索引的使用条件 二、查询性能优化使用 Explain 进行分析 优化数据访问 重构查询方式 三、存储引擎InnoDB MyISAM 比较 四、数据类...

李红欧巴
50分钟前
4
0
堆”和“栈

C++作为一款C语言的升级版本,具有非常强大的功能。它不但能够支持各种程序设计风格,而且还具有C语言的所有功能。我们在这里为大家介绍的是其中一个比较重要的内容,C++内存区域的基本介绍。...

SibylY
今天
4
0
总结:Https

一、介绍 简单理解,https即在http协议的基础上,增加了SSL协议,保障数据传输的安全性。 它由以前的http—–>tcp,改为http——>SSL—–>tcp;https采用了共享密钥加密+公开密钥加密的方式 ...

浮躁的码农
今天
6
0
数据库表与表之间的一对一、一对多、多对多关系

表1 foreign key 表2 多对一:表 1 的多条记录对应表 2 的一条记录 利用foreign key的原理我们可以制作两张表的多对多,一对一关系 多对多: 表1的多条记录可以对应表2的一条记录 表2的多条记...

Garphy
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部