注解方式讲解映射关系
1 One-To-One Unidirectional with Foreign Key
单向关联外键方式
1.1 关系如下
学生和地址关系的例子一个学生住在一个地址上一个地址只能由一个学生占用
1.2 Address 代码:
- package com.daodaofun.domain;
- import javax.persistence.*;
- @Entity
- @Table(name="STUDENT")
- public class Student {
- @Id
- @GeneratedValue
- @Column(name="STUDENT_ID")
- private Long id;
- @Column(name = "FIRST_NAME")
- private String firstName;
- @Column(name = "LAST_NAME")
- private String lastName;
- @OneToOne
- @JoinColumn(name = "ADDRESS_ID")
- private Address address;
- public Student() {
- }
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- public String getFirstName() {
- return firstName;
- }
- public void setFirstName(String firstName) {
- this.firstName = firstName;
- }
- public String getLastName() {
- return lastName;
- }
- public void setLastName(String lastName) {
- this.lastName = lastName;
- }
- public Address getAddress() {
- return address;
- }
- public void setAddress(Address address) {
- this.address = address;
- }
- }
这样可以不用写 hbm.xml, 还是挺方便的此时注意在 Student 一端配置了 JoinColumn, 也就是关联的列, 那么就会在 Student 表当中添加 home_address_id 这一列, 作为外键
外键名称如果需要指定可以使用 @Foreignkey, 遗憾的是这个版本已经是过时了, JPA 的注解没有过时, 但是无法加在这个属性之上, 所以要么使用过时的注解, 要么你忍受, 或者你自行建表
2 One-To-One Bidirectianal
所谓的双向配置也差不了多少, 就是在另外一端一样加上引用即可, 即在 Address 这一段一样持有 Student 并且加上如下注解即可:
- @OneToOne
- private Student student;
但是这样有个问题, 会导致双外键, 这个明显属于冗余, 这个时候我们需要指明谁来主导, 外键由谁来建设的问题, 所以我们需要额外设置一下如下:
- @OneToOne(mappedBy = "address")
- private Student student;
这样就比较合理了
3 Many-To-One Bidirectional
多对一双向
我们以学生与大学的关系为例, 一所大学可以有很多学生
关系图如下:
3.1 University 代码:
-.. 在一的一方配置 OneToMany, 同样的由于我们会将外键设置在多的一方, 所以要将这个建设权交给对方, 所以要加上 mappedBy
- package com.daodaofun.domain;
- import java.util.List;
- import javax.persistence.CascadeType;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.OneToMany;
- import javax.persistence.Table;
- @Entity
- @Table(name="UNIVERSITY")
- public class University {
- @Id
- @GeneratedValue
- @Column(name="UNIVERSITY_ID")
- private Long id;
- @Column(name="NAME")
- private String name;
- @Column(name="COUNTRY")
- private String country;
- @OneToMany(mappedBy = "university",cascade = CascadeType.ALL)
- private List<Student> students;
- public University() {
- }
- public University(String name, String country) {
- this.name = name;
- this.country = country;
- }
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getCountry() {
- return country;
- }
- public void setCountry(String country) {
- this.country = country;
- }
- public List<Student> getStudents() {
- return students;
- }
- public void setStudents(List<Student> students) {
- this.students = students;
- }
- }
3.2 Student 代码:
- package com.daodaofun.domain;
- import javax.persistence.*;
- @Entity
- @Table(name="STUDENT")
- public class Student {
- @Id
- @GeneratedValue
- @Column(name="STUDENT_ID")
- private Long id;
- @Column(name = "FIRST_NAME")
- private String firstName;
- @Column(name = "LAST_NAME")
- private String lastName;
- @ManyToOne(optional = false)
- @JoinColumn(name = "UNIVERSITY_ID")
- private University university;
- public Student() {
- }
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- public String getFirstName() {
- return firstName;
- }
- public void setFirstName(String firstName) {
- this.firstName = firstName;
- }
- public String getLastName() {
- return lastName;
- }
- public void setLastName(String lastName) {
- this.lastName = lastName;
- }
- public University getUniversity() {
- return university;
- }
- public void setUniversity(University university) {
- this.university = university;
- }
- }
在多的一方, 同样的指明建设外键是什么列加上 JoinColumn, 此外这里有一个 optional=false, 这个是什么含义呢?
- (Optional) Whether the association is optional. If set
- to false then a non-null relationship must always exist.
关联关系是否可选, 如果设置为了 false, 那么就必须为非空关系
4 Many-To-Many Bidirectional
双向多对多
在多对多关联中, 使用了一个额外的表 (称为联接表), 其主键是两个关联表的主键的组合换句话说, 联接表和关联表之间存在外键关联表
讨论一个学生和学科关系的例子一名学生可以注册多个科目一个科目可以有多个学生注册
关系图如下:
向这种多多关系其实都是通过一张中间表来体现的
4.1 Student 代码:
- package com.daodaofun.domain;
- import javax.persistence.*;
- import java.util.ArrayList;
- import java.util.List;
- @Entity
- @Table(name="STUDENT")
- public class Student {
- @Id
- @GeneratedValue
- @Column(name="STUDENT_ID")
- private Long id;
- @Column(name = "FIRST_NAME")
- private String firstName;
- @Column(name = "LAST_NAME")
- private String lastName;
- @ManyToMany(cascade = CascadeType.ALL)
- @JoinTable(name = "STUDENT_SUBJECT",joinColumns = {@JoinColumn(name = "STUDENT_ID")},
- inverseJoinColumns = {@JoinColumn(name = "SUBJECT_ID")})
- private List<Subject> subjects = new ArrayList<>();
- public Student() {
- }
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- public String getFirstName() {
- return firstName;
- }
- public void setFirstName(String firstName) {
- this.firstName = firstName;
- }
- public String getLastName() {
- return lastName;
- }
- public void setLastName(String lastName) {
- this.lastName = lastName;
- }
- public List<Subject> getSubjects() {
- return subjects;
- }
- public void setSubjects(List<Subject> subjects) {
- this.subjects = subjects;
- }
- }
4.2 subject 代码:
- package com.daodaofun.domain;
- import javax.persistence.*;
- import java.util.ArrayList;
- import java.util.List;
- @Entity
- @Table(name = "SUBJECT")
- public class Subject {
- @Id
- @GeneratedValue
- @Column(name = "SUBJECT_ID")
- private Long id;
- @Column(name = "name")
- private String name;
- @ManyToMany(mappedBy = "subjects")
- private List<Student> students = new ArrayList<>();
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public List<Student> getStudents() {
- return students;
- }
- public void setStudents(List<Student> students) {
- this.students = students;
- }
- }
这里可以指定任意一方来负责设置表的生成方式, 此处是由 subjects 来设置, 需要注意的是
@JoinTable(name = "STUDENT_SUBJECT",joinColumns = {@JoinColumn(name = "STUDENT_ID")},
inverseJoinColumns = {@JoinColumn(name = "SUBJECT_ID")}) 通过 name 指定了中间表名称, 然后指明需要生成的列, 两列就是 student 表和 subject 表各自的主键
以上几种是比较实用的映射关系方式, hibernate 可以配置映射的方式特别多, 上面几种差不多够用了
来源: http://www.bubuko.com/infodetail-2506378.html