JPA 之 @ManyToMany ,@ManyToOne ,@OneToMany ,@OneToOne,@JoinColumn,@JoinTable

一,简述

  本文只对易尚以上注解的实际用法做一些简单的示例说明,对其内部深入的原理上不做探究

二 , 内容

1. @OneToOne  一对一 关联关系

在数据库中之标示两张表之间的一对一关系,这是hibernate 与jpa之中实体关系最简单的一种,一对一时只需要在两个关联实体的任意一个中,将关联的另一个实体,当做其一个属性,并在该属性上使用@OneToOne注解即可


2.@ManyToOne  与 @OneToMany  一对多与多对一

一对多与多对一,是各种物理数据模型中最常见的关联关系,绝大多数的项目开发中都不可避免,由于hibernate对表关系维护的紧黏连性不如mybaties那么随性(mybaties的实体关系有mapper实体属性映射维护,哪怕数据库中不存在主外键都不影响正常业务的逻辑开发),而@ManyToOne与@OneToMany的最大区别就是在于标注使用的一方是多的一方还是一的一方,简单的区分就是当前Class的实体在这个关联关子中扮演的是多的一方就是用@ManyToOne,反之一的一方则使用@OneToMany,还有一点如下图

JPA 之 @ManyToMany ,@ManyToOne ,@OneToMany ,@OneToOne,@JoinColumn,@JoinTable_第1张图片


一对多和多对一这两个注解可以单向实现,也可以双向实现

下面是单向实现方式:

1. @一对多

这里使用外健关联的方式,博主设置的是运行项目时自动创建表格,该注解会自动生成外健关联关系 

@Entity
 @Table(name = “PARENTS”public class Parents {
     @Id
     @GeneratedValue(generator = “uuid”@GenericGenerator(name = “uuid”,strategy = “uuid2”@ Column(name = “PID”私人字符串ID ;

    @Column(name = “P_NAME”私人字符串名称 ;

    @OneToMany(级联= CascadeType的。ALL,取= FetchType。LAZY

    @JoinColumn(name = “P_ID”,nullable = false
private  Set childSet = new  HashSet ();
省略了设置/获取方法

}
外健在多的一方管理,也就是@OneToMany在许多一方
博主在测试过程中,遇到的大多数问题不是配置的问题,而是实际使用操作中遇到的问题

@OneToMany该映射类在插入数据到数据库时:
父p = ParentRepo.save(父);
在保存数据到家长中时,也会自动把孩子保存进入数据库
@ManyToOne在插入时有不一样的操作方式
2. @多对一

@Entity
 @Table(name = “Child”public class User 实现 Serializable {
     @Id
     @GeneratedValue(generator = “uuid”@GenericGenerator(name = “uuid”,strategy = “uuid2”@ Column(name = “CID “私人字符串ID ;
    @Column(name = “c_name”私人字符串名称 ;
    @Column(name = “c_age”私有整数年龄 ;
    @ManyToOne(级联= CascadeType的ALL,可选= //(fetch=FetchType.LAZY)
 @JoinColumn(NAME = “PARENT_ID” 可为空= 私人 ;    

   省略了设置/获取方法
}
这里需要特别注意取= FetchType.LAZY不能设置为懒加载,在选择操作中会发生返回值异常
在插入操作时:
先对家长执行保存操作,然后把操作的返回值ID设置到子对象中的父对象中,
再执行儿童的保存操作,否则会产生外健异常导致插入失败。
/ *
*三种配置方式:
* 1. @ OneToMany(cascade = {CascadeType.ALL},fetch = FetchType.LAZY,mappedBy =“customId”)
* mappedBy属性用于双向关联实体时使用,
* mappedBy属性:用在双向关联中,把关系的维护权反转;跟hibernate的XML映射中的property-ref一样。
*
* JPA执行步骤:一,插入数据到CUSTOM表,
*二,执行getAddresses()获取需要持久化的ADDRESS(ADDRESS必须代码设置外键CUSTID),
*三,插入数据到ADDRESS表
*
* 2. @ OneToMany(cascade = {CascadeType.ALL},fetch = FetchType.LAZY)
* JPA执行步骤:一,插入数据到CUSTOM表,
*二,执行getAddresses()获取需要持久化的地址(ADDRESS代码不需要设置外键CUSTID),ADDRESS和CUSTOM关系保存在关联表中;
*三,插入数据到ADDRESS表
*四,插入关联信息到CUSTOM_ADDRESS表中
*另外关联表的字段对应关系也可以手工设置,
* @JoinTable(name =“ref_customer_address”,
* joinColumns = {@ JoinColumn(name =“customer_id”,referencedColumnName =“custId”)},
* inverseJoinColumns = {@ JoinColumn(name =“address_id”,referencedColumnName =“addrId”)}
*
* 3. @ OneToMany(cascade = {CascadeType.ALL},fetch = FetchType.LAZY)
* @JoinColumn(name =“customer_id”)对应的是表中的字段,会在最后一步进行该字段的更新
*该设置属于单向关联,该设置需要执行三条SQL操作,不​​推荐; JPA推荐第一种和第二种做法;
* JPA执行步骤如下:一,插入数据到CUSTOM表,
*二,执行getAddresses()获取需要持久化的地址(ADDRESS必须代码设置外键CUSTID或者将外键属性设置为可以为空),
*三,插入数据到ADDRESS表
*四,然后再UPDATE ADDRESS设置外键关系customer_id
*
* 4.另外多端需要初始化一个空数组
*私人收藏<地址>地址=新的ArrayList <地址>();
*
* * /
//级联操作
@OneToMany(cascade = {CascadeType.ALL},fetch = FetchType.LAZY,mappedBy =“customId”)
//双向关联,mappedBy =“customId”不可共存@JoinColumn(name =“customer_id”)
// 2 @JoinTable(name =“ref_customer_address”,
// joinColumns = {@ JoinColumn(name =“customer_id”,referencedColumnName =“custId”)},
// inverseJoinColumns = {@ JoinColumn(name =“address_id”,referencedColumnName =“addrId”)}
//)

(1)ManyToOne(多对一)单向:不产生中间表,但可以用@Joincolumn(name="  ")来指定生成外键的名字,外键在多的一方表中产生!

(2)OneToMany(一对多)单向:会产生中间表,此时可以用@onetoMany @Joincolumn(name=" ")避免产生中间表,并且指定了外键的名字(别看          @joincolumn在一中写着,但它存在在多的那个表中)

(3)OneToMany ,ManyToOne 双向(两个注解一起用的):如果不在@OneToMany中加mappedy属性就会产生中间表,此时通常在@ManyToOne的注            解下再添上注解@Joincolumn(name=" ")来指定外键的名字(说明:多的一方为关系维护端,关系维护端负责外键记录的更新,关系被维护端没有权利更新          外键记录)!(@OneToMany(mappedBy="一对多中,多中一的属性")出现mapby为被维护端|||默认为延迟加载)


用例:@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="child_id")
private OrderChild orderChild;


  @OneToMany(mappedBy =“orderChild”,fetch = FetchType.LAZY,cascade = {CascadeType.MERGE})
  @NotFound(action = NotFoundAction.IGNORE)//代表可以为空,允许为null
  private List goodsList;



冬眠中@ManyToOne默认是立即加载,@一对多默认是懒加载

但是如果加上了@NotFound之后设置的取= FetchType.LAZY是不起作用的,也就是设置@NotFound后变为了立即加载渴望


3. @多对多

JPA 之 @ManyToMany ,@ManyToOne ,@OneToMany ,@OneToOne,@JoinColumn,@JoinTable_第2张图片

JPA 之 @ManyToMany ,@ManyToOne ,@OneToMany ,@OneToOne,@JoinColumn,@JoinTable_第3张图片








你可能感兴趣的:(JAVA基础知识结构,JPA关联关系,@ManyToOne)