@OneToMany、@ManyToOne以及@ManyToMany讲解
一、一对多(@OneToMany)
1、单向一对多模型
假设通过一个客户实体可以获得多个地址信息。
对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。
(1) 映射策略---外键关联
在数据库中表customer和表结构address定义,如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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,代码如下:
|
1
2
3
4
5
6
7
8
|
@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的定义代码如下:
|
1
2
3
4
5
6
7
|
@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,如下:
|
1
2
3
4
5
|
--客户地址关系表create table ref_customer_address ( customer_id int(20) not null, address_id int(20) not null unique) |
此时表customer映射为CustomerEO实体,代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
|
@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,定义如下:
|
1
2
3
4
5
6
7
8
9
|
@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) 默认关联
在数据库底层为两张表添加约束,如下:
|
1
2
3
4
5
6
7
|
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实体如下:
|
1
2
3
4
5
6
7
8
9
10
|
@Entity@Table(name="address")public class AddressEO implements java.io.Serializable { @ManyToOne(cascade = { CascadeType.ALL }) @JoinColumn(name="customer_id") private CustomerEO customer; // ...} |
@ManyToOne定义如下:
|
1
2
3
4
5
6
7
|
@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实体修改为:
|
1
2
3
4
5
6
7
8
9
|
@Entity@Table(name="customer")public class CustomerEO { @OneToMany(mappedBy="customer") private Collection<AddressEO> addresses = new ArrayList<AddressEO>(); // ...} |
其中,@OneToMany标记中的mappedBy属性的值为AddressEO实体中所引用的CustomerEO实体的属性名。
四、多对多(@ManyToMany)
和一对多类型,不在赘述。@ManyToMany标记的定义如下:
|
1
2
3
4
5
6
7
|
@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值的集合。
@OneToMany、@ManyToOne以及@ManyToMany讲解的更多相关文章
- JPA实体关系映射:@ManyToMany多对多关系、@OneToMany@ManyToOne一对多多对一关系和@OneToOne的深度实例解析
JPA实体关系映射:@ManyToMany多对多关系.@OneToMany@ManyToOne一对多多对一关系和@OneToOne的深度实例解析 今天程序中遇到的错误一 org.hibernate.A ...
- hibernate one-to-many many-to-one 双向注解
建表语句: DROP TABLE IF EXISTS `t_company`; CREATE TABLE `t_company` ( `companyId` ) unsigned NOT NULL A ...
- spring-data-jpa 中,如果使用了one-to-many , many-to-one的注释,会在Jackson进行json字符串化的时候出现错误
问题: spring-data-jpa 中,如果使用了one-to-many , many-to-one的注释,会在Jackson 2.7.0 进行json字符串化的时候出现错误. 解决办法: 通过在 ...
- spring boot jpa 多表关联 @OneToOne @OneToMany @ManyToOne@ManyToMany
1.一对一关联 @OneToOne import lombok.Data; import javax.persistence.*; /** * @Author: GWL * @Description: ...
- @OnetoOne @OnetoMany @ManyToOne(2)
在班主任(id,name,bjid) 班级(id name) 学生(id name bjid)的 关系中 班主任一对一关联班级 班级一对多关联学生 @OnetoOne @joinColumn(bjid ...
- one-to-many many-to-one配置解释
one-to-many放在某个文件的配置中,表示这个文件是ONE的一方, 同样的many-to-one放在某个文件的配置中,表示这个文件是many的一方.
- spring-data-jpa——如果使用了one-to-many,many-to-one的注解,在Jackson进行json字符串化时出现错误的解决方案
参考资料: http://blog.csdn.net/remote_roamer/article/details/51330843 http://blog.csdn.net/xiaodaiye/art ...
- 一文搞定 Spring Data JPA
Spring Data JPA 是在 JPA 规范的基础上进行进一步封装的产物,和之前的 JDBC.slf4j 这些一样,只定义了一系列的接口.具体在使用的过程中,一般接入的是 Hibernate 的 ...
- 使用jhipster 加速java web开发
jhipster,中文释义: Java 热爱者! JHipster is a development platform to quickly generate, develop, & depl ...
随机推荐
- (转) s-video vs. composite video vs. component video 几种视频格式详细说明和比较
之前对着几种视频格式认识不是很清晰,所以看数据手册的时候,看的也是稀里糊涂的. 因为项目中需要用到cvbs做视频输入,在元器件选型上,看到tw2867的数据手册上,有这么一句话: The TW2867 ...
- springboot form 提交集合 list
前端代码: function btnSubmit(data) { var url = $('form').attr("action"); $.ajax({ url: url, ty ...
- [转]ESP8266使用详解
本文转自:yangfengwu 原文地址:http://www.cnblogs.com/yangfengwu/p/5205570.html 这两天测试发现一个地方写错了 发送数据的地方 还发现,自己用 ...
- pyremotevbox 用法
>>> import pyremotevbox.vbox as vbox >>> host = vbox.VirtualBoxHost(host='10.0.2.2 ...
- jq dom不存在时绑定事件
$( "a.offsite" ).live( "click", function() { alert( "Goodbye!" ); // j ...
- 前端不容错过的jQuery图片滑块插件
作为前端开发者,我们会碰到很到各种各样的jQuery插件,但老实说,很少有自己写的.今天要分享的几款jQuery图片滑块插件,也就是jQuery焦点图插件,基本上会在每个网站都有应用,可以下载看看,也 ...
- SAX解析XML笔记
关于基本操作,请参考:Java用SAX解析XML,这里不重复造轮子了,以下是个人笔记:
- Fedora26 tftp-server设置
安装tftp-server yum install -y tftp-server 启动软件 systemctl start tftp.socket systemctl enable tftp.soc ...
- HOStringSense大段字符串检测器
下载地址:https://github.com/holtwick/HOStringSense-for-Xcode 修改HOStringSense.xcodeproj工程里的HOStringHelper ...
- UNIX环境编程学习笔记(11)——文件I/O之文件时间以及 utime 函数
lienhua342014-09-16 1 文件的时间 每个文件都有三个时间字段,如表 1 所示. 表 1: 文件的三个时间字段 说明 字段 st_atime 文件数据的最后访问时间 st_mtime ...