关于java:OneToOneManyToOne的具体使用与区别

95次阅读

共计 2397 个字符,预计需要花费 6 分钟才能阅读完成。

在近期的我的项目中我尝试着把本利用 @ManyToOne 注解的中央应用 @OneToOne 注解,本认为进行存储或者查问等操作时会产生谬误然而并没有产生任何谬误,所有操作都能够失常执行。
所以首先我想看一下在数据库中生成的外键是否雷同。

  @ApiModelProperty("车辆品牌")
  @ManyToOne
  private VehicleBrand brand;

  @ApiModelProperty("车辆类型")
  @OneToOne
  private VehicleType type;

咱们会发现目前在数据库中没有任何差异,那么这时我就想通过查看他们的源代码来比拟一下。

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ManyToOne {Class targetEntity() default void.class;

  CascadeType[] cascade() default {};

  FetchType fetch() default FetchType.EAGER;

  boolean optional() default true;}
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface OneToOne {Class targetEntity() default void.class;

  CascadeType[] cascade() default {};

  FetchType fetch() default FetchType.EAGER;

  boolean optional() default true;

  String mappedBy() default "";

  boolean orphanRemoval() default false;}

通过比照咱们能够发现 @OneToOne 只比 @ManyToOne 多了两项内容,mappedBy 和 orphanRemoval。其余部分完全一致。

MappedBy

只有 OneToOne,OneToMany,ManyToMany 上才有 mappedBy 属性,ManyToOne 不存在该属性;
mappedBy 标签肯定是定义在被领有方的,他指向领有方;

mappedBy 示意申明本人不是一对多的关系保护端,由对方来保护,是在一的一方进行申明的。mappedBy 的值应该为一的一方的表名。

mappedBy 在 Stack Overflow 上有着更具体的解释
询问者问题:mappedBy 作用

Foo 实体:@ManyToMany(mappedBy = "foos")
private Set<Bar> bars
Bar 实体:@ManyToMany
private Set<Foo> foos

将其中的一个答复翻译过去就是:

如果关联是双向的,则一方必须是所有者,另一方必须是反向端(即在更新关联表中的关系值时将疏忽它):所以,具备 mappedby 属性的边是相同的边。没有 mappedby 属性的一方是所有者。(mappedy 在 Foo 中)
所有者侧是 Hibernate 所查看的哪一个关联存在的方。因而,例如,如果在 Bar 的 foo 汇合中增加 foo,hibernate 将在表中插入一个新行。相同,如果在 Foo 的 bar 汇合中增加一个 bar,则数据库中不会批改任何内容。

尝试着对以上内容进行论证
假如 Klass 和 Teacher 两个实体,他们的关系为多对多;

@Entity
public class Teacher  {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    
    @ManyToMany(mappedBy = "teacherList")
    private List<Klass> klassList = new ArrayList<>();}
@Entity
public class Teacher  {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    //teacher 领有 mappedBy 属性的 Klass
    @ManyToMany(mappedBy = "teacherList")
    private List<Klass> klassList = new ArrayList<>();}

这时从 klas 插入 teacher 是能够胜利的,而从 teacher 插入 klass 是没法胜利的。

所以我尝试着在 VehicleType 实体中申明 vehicle。

  @OneToOne(mappedBy = "type")
  private Vehicle vehicle;

之后我再关上我的项目中相应页面时就会产生报错:

其中的 More than one row with the given identifier was found:翻译过去就是:找到了多个具备给定标识符的行。也就合乎咱们的预期。因为之前对 mappedBy 的认知不清晰,也就没有要给相关联实体削减 mappedBy 的习惯。

由此能够得悉 mappedBy 不仅仅能够做到下面那样的规定保护方的性能,还能够做到检测存储谬误的性能,所以在理论的编写中增加对应的 mappedBy 还是很有必要的。

至于注解中的其余属性则是对应着 jpa 级联(Cascade) 操作

因为 重复性的操作非常繁缛,尤其是在解决多个彼此关联对象状况下,此时咱们能够应用级联(Cascade)操作。级联 在关联映射中是个重要的概念,指当被动方对象执行操作时,被关联对象(被动方)是否同步执行同一操作。
因为临时并未遇到相应的问题也就没有深刻理解,能够先对此有个概念,之后遇到相应问题时再来认真理解。
参考文章:jpa 级联 (Cascade) 操作

正文完
 0