单向一对多的关联关系

具体体现:1的一方有n的一方的集合的引用,n的一方却没有1的一方的引用

举个例子:顾客Customer对订单Order是一个单向一对多的关联关系。Customer一方有对Order的集合的引用。而Order却没有对Customer的引用;

“一对多”的物理意义就是:一个客户可以有多个订单,而一个订单只能归属于一个客户。

“单向”的物理意义就是:客户知道自己有哪些订单,但是订单却不知道自己属于哪个客户(这个容易让人接受一点儿!!!但是,不满足某些业务需求)

同样的,下面看看“单向一对多”的“Customer对Order”会有什么变化:

Order实体的属性(Order中没有对Customer的引用):

1 @Table(name="t_single_one2many_order")
2 @Entity
3 public class Order1 {
4
5     private Integer id;
6     private String orderName;
7
8     //省略getter、setter方法...
9 }

Customer实体的属性(Customer中有对Order的集合的引用):

 1 @Table(name="t_single_one2many_customer")
 2 @Entity
 3 public class Customer1 {
 4
 5     private Integer id;
 6     private String lastName;
 7
 8     private String email;
 9     private int age;
10
11     private Date birthday;
12
13     private Date createdTime;
14
15     //Customer1中有对Order1的集合引用  
16     private Set<Order1> orders = new HashSet<Order1>();
17
18     //省略getter、setter方法...
19 }

映射单向一对多的关联关系有两个要点:

1、利用@OneToMany注解进行一对多的映射;

2、利用@JoinColumn来映射外键列的名称;

注意的点:

1、@OneToMany的默认检索策略为延迟加载策略,可以通过设置其属性fetch=FetchType.EAGER来修改为立即检索策略;

2、@OneToMany设置的单向一对多关联在其默认情况下可以删除1的一方。

  处理方式:首先将其关联的n的一方数据表的所有外键都设置为null,然后再删除1的一方。可以通过设置@OneToMany的属性cascade={CascadeType.REMOVE}来设置为级联删除(删除1的一方的同时把多的一方也同时删除,还可以设置其它的删除策略

在实体类中,属性可以分为两种:1、集合属性; 2、非集合属性;

一个大体的原则就是:1、对集合属性默认采用懒加载策略;2、对非集合属性默认采用立即检索策略;

这种默认检索策略是有道理的:1、检索的时候我们并不知道集合中到底包含了多少条记录,可能是几条,也可能是几十亿条记录。如果对一个庞大的集合属性采用立即检索策略,那么很有可能直接将内存全部占用了(比如说,集合中包含了100亿条记录),系统直接崩溃。2、对一个非集合属性而言,即便是一个其它实体类的引用(该引用中的集合依然会采用延迟检索)所占资源也是十分有限,不会像检索集合那样直接脱离我们的掌控。所以,对于非集合属性默认采用立即检索策略。

对于单向1-n而言,保存的顺序没有差别,都会有update语句发送。

List_1. Order1实体的代码(不包含对1的一方的引用,不需要做任何关于映射的注解

 1 package com.magicode.jpa.single.one2many;
 2
 3 import javax.persistence.Column;
 4 import javax.persistence.Entity;
 5 import javax.persistence.GeneratedValue;
 6 import javax.persistence.GenerationType;
 7 import javax.persistence.Id;
 8 import javax.persistence.Table;
 9 import javax.persistence.TableGenerator;
10
11 @Table(name="t_single_one2many_order")
12 @Entity
13 public class Order1 {
14
15     private Integer id;
16     private String orderName;
17
18     @TableGenerator(name="order_id_generator_1",
19             table="t_id_generator",
20             pkColumnName="PK_NAME",
21             pkColumnValue="seedId_t_order_1",
22             valueColumnName="PK_VALUE",
23             initialValue=0,
24             allocationSize=20)
25     @GeneratedValue(generator="order_id_generator_1", strategy=GenerationType.TABLE)
26     @Id
27     @Column(name="ID")
28     public Integer getId() {
29         return id;
30     }
31
32     @Column(name="ORDER_NAME")
33     public String getOrderName() {
34         return orderName;
35     }
36
37     @SuppressWarnings("unused")
38     private void setId(Integer id) {
39         this.id = id;
40     }
41
42     public void setOrderName(String orderName) {
43         this.orderName = orderName;
44     }
45
46 }

Order1.java作为n的一方不需要任何关于映射的注解

List_2. Customer1实体的代码(包含有对n的一方的集合的引用

  1 package com.magicode.jpa.single.one2many;
  2
  3 import java.util.Date;
  4 import java.util.HashSet;
  5 import java.util.Set;
  6
  7 import javax.persistence.CascadeType;
  8 import javax.persistence.Column;
  9 import javax.persistence.Entity;
 10 import javax.persistence.FetchType;
 11 import javax.persistence.GeneratedValue;
 12 import javax.persistence.GenerationType;
 13 import javax.persistence.Id;
 14 import javax.persistence.JoinColumn;
 15 import javax.persistence.OneToMany;
 16 import javax.persistence.Table;
 17 import javax.persistence.TableGenerator;
 18 //import javax.persistence.TableGenerator;
 19 import javax.persistence.Temporal;
 20 import javax.persistence.TemporalType;
 21 import javax.persistence.Transient;
 22
 23 /**
 24  * @Entity 用于注明该类是一个实体类
 25  * @Table(name="t_customer") 表明该实体类映射到数据库的 t_customer 表
 26  */
 27 @Table(name="t_single_one2many_customer")
 28 @Entity
 29 public class Customer1 {
 30
 31     private Integer id;
 32     private String lastName;
 33
 34     private String email;
 35     private int age;
 36
 37     private Date birthday;
 38
 39     private Date createdTime;
 40
 41     private Set<Order1> orders = new HashSet<Order1>();
 42
 43     @TableGenerator(name="ID_GENERATOR_1",
 44             table="t_id_generator",
 45             pkColumnName="PK_NAME",
 46             pkColumnValue="seedId_t_customer_1",
 47             valueColumnName="PK_VALUE",
 48             allocationSize=20,
 49             initialValue=10
 50             )
 51     @GeneratedValue(strategy=GenerationType.TABLE, generator="ID_GENERATOR_1")
 52     @Id
 53     @Column(name="ID")
 54     public Integer getId() {
 55         return id;
 56     }
 57
 58     /**
 59      * 1、单向一对多的关联关系使用@OneToMany注解进行映射
 60      * 2、利用@JoinColumn来映射外键列的名称
 61      * 3、@OneToMany在默认情况下使用懒加载的检索策略,可以通过fetch=FetchType.EAGER
 62      *    来修改为立即加载策略;
 63      * 4、单向一对多可以删除1的一方,此时JPA的做法是将多的一方的外键全部置为null,然后再删除1的一方
 64      *    可以通过设置cascade={CascadeType.REMOVE}来设置为级联删除(删除1的一方的同时把多的
 65      *    一方也同时删除,还可以设置其它的删除策略)
 66      */
 67     @OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.REMOVE})
 68     @JoinColumn(name="CUSTOMER_ID")
 69     public Set<Order1> getOrders() {
 70         return orders;
 71     }
 72
 73     public void setOrders(Set<Order1> orders) {
 74         this.orders = orders;
 75     }
 76
 77     @Column(name="LAST_NAME", length=50, nullable=false)
 78     public String getLastName() {
 79         return lastName;
 80     }
 81
 82     @Column(name="BIRTHDAY")
 83     @Temporal(TemporalType.DATE)
 84     public Date getBirthday() {
 85         return birthday;
 86     }
 87
 88     @Column(name="CREATED_TIME", columnDefinition="DATE")
 89     public Date getCreatedTime() {
 90         return createdTime;
 91     }
 92
 93     @Column(name="EMAIL",columnDefinition="TEXT")
 94     public String getEmail() {
 95         return email;
 96     }
 97
 98     /*
 99      * 工具方法,不需要映射为数据表的一列
100      */
101     @Transient
102     public String getInfo(){
103         return "lastName: " + lastName + " email: " + email;
104     }
105
106     @Column(name="AGE")
107     public int getAge() {
108         return age;
109     }
110
111     @SuppressWarnings("unused")
112     private void setId(Integer id) {
113         this.id = id;
114     }
115
116     public void setLastName(String lastName) {
117         this.lastName = lastName;
118     }
119
120     public void setEmail(String email) {
121         this.email = email;
122     }
123
124     public void setAge(int age) {
125         this.age = age;
126     }
127
128     public void setBirthday(Date birthday) {
129         this.birthday = birthday;
130     }
131
132     public void setCreatedTime(Date createdTime) {
133         this.createdTime = createdTime;
134     }
135
136 }

List_3. 测试代码

 1 package com.magicode.jpa.single.one2many;
 2
 3 import java.util.Date;
 4
 5 import javax.persistence.EntityManager;
 6 import javax.persistence.EntityManagerFactory;
 7 import javax.persistence.EntityTransaction;
 8 import javax.persistence.Persistence;
 9
10 import org.junit.After;
11 import org.junit.Before;
12 import org.junit.Test;
13
14 public class One2ManyTest {
15
16     EntityManagerFactory emf = null;
17     EntityManager em = null;
18     EntityTransaction transaction = null;
19
20     @Before
21     public void before(){
22         emf = Persistence.createEntityManagerFactory("jpa-1");
23         em = emf.createEntityManager();
24         transaction = em.getTransaction();
25         transaction.begin();
26     }
27
28     @After
29     public void after(){
30         transaction.commit();
31         em.close();
32         emf.close();
33     }
34
35     @Test
36     public void testPersist(){
37
38         for(int i = 0; i < 3; i++){
39             char c = (char) ('A' + i);
40             String strName = (" " + c + c).trim();
41             int age = 25 + i;
42
43             Customer1 customer = new Customer1();
44             customer.setAge(age);
45             customer.setEmail(strName + "@163.com");
46             customer.setLastName(strName);
47             customer.setBirthday(new Date());
48             customer.setCreatedTime(new Date());
49
50             Order1 order1 = new Order1();
51             order1.setOrderName("O-" + strName + "-1");
52
53             Order1 order2 = new Order1();
54             order2.setOrderName("O-" + strName + "-2");
55
56             //设置关联关系
57             customer.getOrders().add(order1);
58             customer.getOrders().add(order2);
59
60             /**
61              * 保存的顺序没有区别,无论什么顺序都会有update语句发送
62              */
63             em.persist(customer);
64             em.persist(order1);
65             em.persist(order2);
66         }
67     }
68
69 }

转载于:https://www.cnblogs.com/lj95801/p/5005789.html

7、单向一对多的关联关系(1的一方有n的一方的集合属性,n的一方却没有1的一方的引用)...相关推荐

  1. JPA中实现单向一对多的关联关系

    场景 JPA入门简介与搭建HelloWorld(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937 ...

  2. JPA中实现双向一对多的关联关系

    场景 JPA入门简介与搭建HelloWorld(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937 ...

  3. Hibernate - 单向一对多关联关系映射

    上篇博文描述了Hibernate - 单向多对一关联关系映射,本篇博文继续学习单向一对多关系映射. 这里Customer:Order= 1:N,外键保存在Order表中. [1]修改Customer和 ...

  4. 06章 映射一对多双向关联关系、以及cascade、inverse属性

    当类与类之间建立了关联,就可以方便的从一个对象导航到另一个对象.或者通过集合导航到一组对象.例如: 对于给定的Emp对象,如果想获得与它关联的Dept对象,只要调用如下方法 Dept dept=emp ...

  5. hibernate映射一对多双向关联关系实例

    在电子商务应用中,经常会有这样的需求:根据给定的客户,得到该客户的所有订单:根据给定的订单,得到该订单的所属客户.对于这种双向关联的情况,在Hibernate应用中,也有人叫多对一双向关联,只是叫法不 ...

  6. 单向一对多和双向一对多

    <深入浅出Hibernate>中对单向一对多和双向一对多进行了一些介绍,其中提到:"由于是单向关联,为了保持关联关系,只能通过主控方对被控方进行及联更新."也就是说,对 ...

  7. jpa单向一对多关联映射

    如果在一的@OneToMany有@manyToOne则是双向一对多关联,如果在多的那面没有@manyToOne关联则是单向一对多关联 class和student是一对多的关系 表结构 student ...

  8. JPA(五):映射关联关系------映射单向多对一的关联关系

    映射单向多对一的关联关系 新建Customer.java: package com.dx.jpa.singlemanytoone;import java.util.Date;import javax. ...

  9. hibernate单向一对多关联

    2019独角兽企业重金招聘Python工程师标准>>> 有这样一个应用场景,有一张用户表(APM_USER),一张部门表(APM_DEPT).用户和部门之间的关系是多对一(many ...

最新文章

  1. 翻译连载 | JavaScript轻量级函数式编程-第4章:组合函数 |《你不知道的JS》姊妹篇...
  2. 程序员需要有多懒 ?- cocos2d-x 数学函数、常用宏粗整理 - by Glede
  3. 初始化列表||类对象作为类成员|| 静态成员
  4. (转)常用正则表达式
  5. Leecode02-两数相加——Leecode热题100道系列
  6. 涨知识了!阿里、百度、腾讯的名字竟然是这样来的
  7. PHP文件操作---文件file
  8. python 使用 with open() as 读写文件-给Python学习者的文件读写指南(含基础与进阶)...
  9. java将map输出到d盘_java后台的“/”相对路径不是代表webroot吗,为什么在这里代表了d盘,测试的文件都传到了d盘呀?...
  10. J2EE框架DDoS漏洞预警公告
  11. LabVIEW控制Arduino实现红外测距(进阶篇—6)
  12. JAVA Future类详解
  13. 7月1日天刀服务器维护,天涯明月刀7月1日满级新服_天刀满级新服天命风流入君怀_3DM网游...
  14. CodeSniffer使用教程
  15. iOS:基于Photos框架的图片选择器以及创建自定义相册
  16. c/c++实现简单的贪吃蛇可视化游戏
  17. 组播地址分类 Cyrus
  18. Hive内表和外表的区别
  19. win10调节桌面显示计算机,Win10系统电脑屏幕的饱和度如何调整?
  20. 怎么理解预训练模型?

热门文章

  1. Go 变量及基本数据类型3
  2. [九省联考2018]IIIDX
  3. P1282 多米诺骨牌 (差值DP+背包)
  4. POJ 2456 Aggressive cows ( 二分 贪心 )
  5. p,br,hn,b,i,u,s,sup,sub标签
  6. Python使用xlwt模块 操作Excel文件
  7. 服务器导出服务器时间转换浏览器端时区
  8. API(Application Programming Interface,应用程序编程接口)
  9. 2009-12-12
  10. 以获客为目标 ,首席增长官从0到1实现用户增长