@ManyToOne 注解

@ManyToOne 注解定义了与另一个具有多对一多重性的实体类的单值关联。通常不需要明确指定目标实体类型,它可以从被引用的对象类型推断出来。例如:

// 下面的目标实体类型为 Custormer,不需要手动指定
@ManyToOne(optional=false) 
private Customer customer;

如果关系是双向的,则不具有所有权的 OneToMany 实体端必须使用 mappdBy 属性来指定作为关系所有者的实体的关系字段或属性。

实例1:假如我们拥有两个实体,分别是教师(Teacher)和学生(Student),Teacher 和 Student 是一对多关系(一个教师可以拥有多个学生)。那么在 JPA 中,如何表示一对多的双向关联呢?

JPA 使用 @OneToMany 和 @ManyToOne 注解来标识一对多的双向关联。One 端(Teacher)使用 @OneToMany 注解,Many 端(Student)使用 @ManyToOne 注解。

在 JPA 规范中,一对多的双向关系由多端(Student)来维护。就是说多端(Student)为关系维护端,负责关系的增删改查。一端(Teacher)则为关系被维护端,不能维护关系。

One 端(Teacher)的 @OneToMany 注解的 mappedBy="teacher" 属性表明 Teacher 是关系被维护端。

Many 端(Student)使用 @ManyToOne 和 @JoinColumn 注解来指定属性 TEACHER_ID 是 Student 表中的关联字段(外键)。

Java 代码

Teacher.java 类

@Data
@Entity
@Table
public class Teacher {
    @Id
    @GeneratedValue
    private int id;

    @Column
    private String name;

    @OneToMany(mappedBy = "teacher")
    private List<Student> studentList;
}

Student.java 类

@Data
@Entity
@Table
public class Student {
    @Id
    @GeneratedValue
    private int id;

    @Column
    private String name;

    @ManyToOne
    @JoinColumn(name = "teacher_id")
    private Teacher teacher;
}

生成的 SQL 语句

CREATE TABLE `teacher` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `student` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `teacher_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `I_STUDENT_TEACHER` (`teacher_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

@ManyToOne 注解可以在可嵌入类内使用,以指定从可嵌入类到实体类的关系。如果关系是双向的,则不具有所有权的 OneToMany 实体端必须使用 OneToMany 注解的 mappdBy 元素来指定关系拥有端的可嵌入字段或属性的关系字段或属性。在 mappedBy 元素中必须使用点(“.”)符号语法来指示嵌入属性中的关系属性。与点符号一起使用的每个标识符的值是相应嵌入字段或属性的名称。

实例2:将学生中的 name 和关于 Teacher 的信息提取到单独的 StudentExt 嵌入类中,代码如下:

Java 代码

Teacher.java 类

@Data
@Entity
@Table
public class Teacher {
    @Id
    @GeneratedValue
    private int id;

    @Column
    private String name;

    @OneToMany(mappedBy = "studentExt.teacher")
    private List<Student> studentList;
}

Student.java 类

@Data
@Entity
@Table
public class Student {
    @Id
    @GeneratedValue
    private int id;

    @Embedded
    private StudentExt studentExt;
}

StudentExt.java

@Data
@Embeddable
public class StudentExt {

    @Column
    private String name;

    @ManyToOne
    @JoinColumn(name = "teacher_id")
    private Teacher teacher;
}

生成的SQL语句

CREATE TABLE `teacher` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `student` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `teacher_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `I_STUDENT_TEACHER` (`teacher_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

@ManyToOne 注解属性详情:

  • targetEntity:(可选)作为关联目标的实体类,默认为存储关联的字段或属性的类型。默认值 void.class

  • cascade:(可选)必须级联到关联目标的操作,默认情况下,不会级联任何操作。默认值 {}

  • fetch:(可选)关联是应该延迟加载还是必须立刻加载。立刻加载策略是持久性提供程序运行时的一个要求,即必须立刻获取关联的实体。懒惰策略是对持久性提供程序运行时的一个提示。默认值 javax.persistence.FetchType.EAGER 

  • optional:(可选)关联是否为可选。如果设置为 false,则必须始终存在非空关系。默认为 true

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号