单向一对多的关联关系

具体体现: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的一方不需要任何关于映射的注解

相关文章:

  • 2022-01-04
  • 2022-12-23
  • 2021-07-13
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-08
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-06-28
  • 2021-05-18
  • 2021-10-23
  • 2021-12-18
相关资源
相似解决方案