zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    GNU make查找makefile的顺序
    解决ssh登录过慢的问题
    大小端转换定义结构体的技巧
    git解决git apply时遇到trailing whitespace问题
    Qualcomm Atheros AR9485 无线网卡驱动问题
    tcpdump入门笔记
    Linux内核探索之路——关于书
    Ubuntu下最好用的词典Golden Dict设置支持有道
    ubuntu14.04完美安装并设置搜狗输入法
    ubuntu网络已禁用的解决方案
  • 原文地址:https://www.cnblogs.com/lj95801/p/5005789.html
Copyright © 2011-2022 走看看