>>分享孙卫琴的Java技术专稿和著作 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 14962 个阅读者 刷新本主题
 * 贴子主题:  【持久化专题】映射一对多双向关联关系 回复文章 点赞(0)  收藏  
作者:sunweiqin    发表时间:2021-05-05 06:58:41     消息  查看  搜索  好友  邮件  复制  引用

本文参考《精通JPA与Hibernate:Java对象持久化技术详解》,作者:孙卫琴,清华大学出版社出版

   当类与类之间建立了关联,就可以方便地从一个对象导航到另一个或者一组与它关联的对象。例如,对于给定的Order对象,如果想获得与它关联的Customer对象,只要调用如下方法:
//从Order对象导航到关联的Customer对象
Customer customer=order.getCustomer();

在Order类中,用@ManyToOne注解映射customer属性:

  @ManyToOne(targetEntity =Customer.class)
  @JoinColumn(name="CUSTOMER_ID")
  private Customer customer;

对于给定的客户,查询该客户的所有订单,只需要调用customer.getOrders()方法。

     Hibernate要求在持久化类中定义集合类属性时,必须把属性声明为接口类型,如java.util.Set、java.util.Map和java.util.List。声明为接口可以提高持久化类的透明性,当Hibernate调用setOrders(Set orders)方法时,传递的参数是Hibernate自定义的实现该接口的类的实例。如果把orders声明为java.util.HashSet类型(它是java.util.Set接口的一个实现类),就强迫Hibernate只能把HashSet类的实例传给setOrders()方法。

在定义Customer类的orders集合属性时,通常把它初始化为集合实现类的一个实例,例如:

private Set orders=new HashSet();

这可以提高程序的健壮性,避免应用程序访问取值为null的orders集合的方法而抛出NullPointerException。例如,以下程序访问Customer对象的orders集合,即使orders集合中不包含任何元素,但是调用orders.iterator()方法也不会抛出NullPointerException异常,因为orders集合并不为null:

Set orders=customer.getOrders();
Iterator it=orders.iterator();
while(it.hasNext()){
  ……
}

  以下是Customer.java的源程序。

@Entity@Table(name="CUSTOMERS")
public class Customer  implements java.io.Serializable {
  @Id
  @GeneratedValue(generator="increment")
  @GenericGenerator(name="increment", strategy = "increment")
  @Column(name="ID")
  private Long id;

  @Column(name="NAME")
  private String name;

  @OneToMany(mappedBy="customer",
             targetEntity=Order.class,
             cascade=CascadeType.ALL)
  private Set orders = new HashSet();
  
  //此处省略构造方法,以及id和name属性的访问方法
  ……  
  public Set getOrders(){
    return orders;
  }
  public void setOrders(Set orders) {
    this.orders=orders;
  }
}

          对于Customer类的orders属性,由于在CUSTOMERS表中没有直接与orders属性对应的字段,因此不能用@Column注解来映射orders属性,而是要使用@OneToMany注解。@OneToMany注解包括以下属性。    
  • targetEntity属性:指定orders集合中存放的是Order对象。
  • mappedBy属性:指定Order类中的customer属性引用所关联的Customer对象。
  • cascade:当取值为CascadeType.ALL,表示会执行级联保存、更新和删除等操作。
在双向关联关系中,可以把一方称为主动方,另一方称为被动方。主动方会负责维护关联关系,而被动方不负责维护关联关系。被动方用@OneToOne、@OneToMany和@ManyToMany注解来映射,并且设置了mappedBy属性。

在Customer类与Order类的一对多双向关联关系中,Customer类为“一”的一方,Order类为“多”的一方。Customer类作为“一”的一方,它的@OneToMany注解设置了mappedBy属性,因此Customer类是被动方,而Order类是主动方,负责维护两者之间的关联关系。

所谓维护关联关系,有两层含义:
  • (1)指在数据库中,主动方Order类对应的ORDERS表的外键参照CUSTOMERS表。假如Customer类的@OneToMany注解没有使用mappeBy属性,那么Customer类变成主动方,需要维护与Order类的关联关系,此时需要创建额外的CUSTOMER_ORDER连接表。
  • (2)Hibernate会根据主动方的持久化对象的关联关系的变化去同步更新数据库。
    点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小
程序猿的技术大观园:www.javathinker.net





[这个贴子最后由 admin 在 2021-10-09 10:45:24 重新编辑]
  Java面向对象编程-->输入与输出(下)
  JavaWeb开发-->使用过滤器
  JSP与Hibernate开发-->映射一对多关联关系
  Java网络编程-->客户端协议处理框架
  精通Spring-->绑定表单
  Vue3开发-->Vue Router路由管理器
  【Vue.js技术专题】注册全局组件和局部组件
  【Vue.js技术专题】Vue组件的单向数据流
  【Vue.js技术专题】CSS中DOM元素的过渡模式
  【Java基础编程专题】浮点数的格式化以及运算精度
  【Spring专题】控制器对象的生命周期
  【Spring专题】通过JPA API实现Repository接口
  【持久化专题】JPA API的级联操作
  【持久化专题】对象-关系的映射概念
  【持久化专题】FetchType.LAZY延迟检索策略
  【持久化专题】Spring与Hibernate与JPA的整合
  【Java网络编程专题】盘点用Java抓取HTTP服务器和FTP服务器的...
  【Java基础编程专题】Java集合的批量操作
  【Java基础编程专题】Java集合与数组的互换
  【Java基础编程专题】为什么说:继承关系最大的弱点就是打破...
  我的计算机书籍创作心得
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。