7、单向一对多的关联关系(1的一方有n的一方的集合属性,n的一方却没有1的一方的引用)...
单向一对多的关联关系
具体体现: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的一方的引用)...相关推荐
- JPA中实现单向一对多的关联关系
场景 JPA入门简介与搭建HelloWorld(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937 ...
- JPA中实现双向一对多的关联关系
场景 JPA入门简介与搭建HelloWorld(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937 ...
- Hibernate - 单向一对多关联关系映射
上篇博文描述了Hibernate - 单向多对一关联关系映射,本篇博文继续学习单向一对多关系映射. 这里Customer:Order= 1:N,外键保存在Order表中. [1]修改Customer和 ...
- 06章 映射一对多双向关联关系、以及cascade、inverse属性
当类与类之间建立了关联,就可以方便的从一个对象导航到另一个对象.或者通过集合导航到一组对象.例如: 对于给定的Emp对象,如果想获得与它关联的Dept对象,只要调用如下方法 Dept dept=emp ...
- hibernate映射一对多双向关联关系实例
在电子商务应用中,经常会有这样的需求:根据给定的客户,得到该客户的所有订单:根据给定的订单,得到该订单的所属客户.对于这种双向关联的情况,在Hibernate应用中,也有人叫多对一双向关联,只是叫法不 ...
- 单向一对多和双向一对多
<深入浅出Hibernate>中对单向一对多和双向一对多进行了一些介绍,其中提到:"由于是单向关联,为了保持关联关系,只能通过主控方对被控方进行及联更新."也就是说,对 ...
- jpa单向一对多关联映射
如果在一的@OneToMany有@manyToOne则是双向一对多关联,如果在多的那面没有@manyToOne关联则是单向一对多关联 class和student是一对多的关系 表结构 student ...
- JPA(五):映射关联关系------映射单向多对一的关联关系
映射单向多对一的关联关系 新建Customer.java: package com.dx.jpa.singlemanytoone;import java.util.Date;import javax. ...
- hibernate单向一对多关联
2019独角兽企业重金招聘Python工程师标准>>> 有这样一个应用场景,有一张用户表(APM_USER),一张部门表(APM_DEPT).用户和部门之间的关系是多对一(many ...
最新文章
- 翻译连载 | JavaScript轻量级函数式编程-第4章:组合函数 |《你不知道的JS》姊妹篇...
- 程序员需要有多懒 ?- cocos2d-x 数学函数、常用宏粗整理 - by Glede
- 初始化列表||类对象作为类成员|| 静态成员
- (转)常用正则表达式
- Leecode02-两数相加——Leecode热题100道系列
- 涨知识了!阿里、百度、腾讯的名字竟然是这样来的
- PHP文件操作---文件file
- python 使用 with open() as 读写文件-给Python学习者的文件读写指南(含基础与进阶)...
- java将map输出到d盘_java后台的“/”相对路径不是代表webroot吗,为什么在这里代表了d盘,测试的文件都传到了d盘呀?...
- J2EE框架DDoS漏洞预警公告
- LabVIEW控制Arduino实现红外测距(进阶篇—6)
- JAVA Future类详解
- 7月1日天刀服务器维护,天涯明月刀7月1日满级新服_天刀满级新服天命风流入君怀_3DM网游...
- CodeSniffer使用教程
- iOS:基于Photos框架的图片选择器以及创建自定义相册
- c/c++实现简单的贪吃蛇可视化游戏
- 组播地址分类 Cyrus
- Hive内表和外表的区别
- win10调节桌面显示计算机,Win10系统电脑屏幕的饱和度如何调整?
- 怎么理解预训练模型?
热门文章
- Go 变量及基本数据类型3
- [九省联考2018]IIIDX
- P1282 多米诺骨牌 (差值DP+背包)
- POJ 2456 Aggressive cows ( 二分 贪心 )
- p,br,hn,b,i,u,s,sup,sub标签
- Python使用xlwt模块 操作Excel文件
- 服务器导出服务器时间转换浏览器端时区
- API(Application Programming Interface,应用程序编程接口)
- 2009-12-12
- 以获客为目标 ,首席增长官从0到1实现用户增长