注解方式讲解映射关系
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可以配置映射的方式特别多,上面几种差不多够用了。
hibernate注解方式讲解映射关系
原文地址:https://www.cnblogs.com/qiudaozhang/p/8468718.html