Hibernate实体映射关系

Hibernate中实体映射关系可分为如下几种:

  • 单边一对一,双边一对一
  • 单边一对多,单边多对一
  • 双边一对多,双边多对一
  • 单边多对多,双边多对多
  • 主键相同的单双边一对一

注解

标注在类之前

@Entity:表示所标注的Java类是实体。

@Table:表示所标注的Java类所对应的数据库表,其中name属性对应表名。

标注在变量之前

@Id:表示对应的变量表示为主键。

@GeneratedValue:其中的strategy属性用于表示主键的生成策略,共包含四种GenerationType.AUTO(主键由程序控制),GenerationType.IDENTITY(主键由数据库自动生成,自动增长型),GenerationType.SEQUENCE(根据底层数据库的序列来生成主键,条件是数据库支持序列),GenerationType.TABLE(使用一个特定的数据库表格来保存主键)。

@JoinColumn:

@OneToOne:

  1. cascade:配置级联方式,有PERSIST、REMOVE、MERGE、REFRESH等几种取值,分别表示在保存、删除、修改、刷新对应的类时,会自动在数据库中保存、删除、修改、刷新属于它的对象,ALL则表示所有动作皆级联。
  2. mappedBy:在双向关联时,用于映射。

@OneToMany:cascade,mappedBy属性同上。 

@ManyToOne:cascade,mappedBy属性同上。 

@ManyToMany:mappedBy属性同上。

@PrimaryKeyJoinColumn:用于设置共同主键。

@JoinColumn:添加一个新列,name属性表示新列的名称。

@JoinTable:添加一个新表。

单边一对一,双边一对一

单边一对一:例如一个人只能拥有一个身份证。

@Entity
@Table(name="t_person")
public class Person {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private String id;

  @OneToOne(cascade={CascadeType.ALL})
  @JoinColumn(name="person_id", unique=true)
  private IdCard idCard;
}

@Entity
@Table(name="t_idcard")
public class IdCard {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private String id;

  private String name;

  private String sex;
}

 双边一对一:例如一个丈夫只能拥有一个妻子,一个妻子也只能拥有一个丈夫。

@Entity
public class Husband {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;
   
  @OneToOne
  @JoinColumn(name="wifeId")
  private Wife wife;
}

@Entity
public class Wife {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;

  @OneToOne(mappedBy="wife")
  private Husband husband;  
}

 单边一对多,单边多对一

单边一对多:例如一个班级有多个学生,班级类中包含了学生类的集合

@Entity
@Table(name="t_class")
public class Class {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;

  @OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
  @JoinColumn(name="classid")
  private Set<Student> students = new HashSet<Student>();
}

@Entity
@Table(name="t_student")
public class Student {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;
}

单边多对一:例如一个班级有多个学生,学生类中包含了班级类

@Entity
@Table(name="t_class")
public class Class {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;
}

@Entity
@Table(name="t_student")
public class Student {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;

  @ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
  @JoinColumn(name="classid")
  private Class class;
}

 双边一对多,双边多对一

例如一个班级有多个学生,班级类中包含了学生类的集合,学生类中包含了班级类。双边关系中,控制权一般交给多方,因此在@OneToMany无需配置数据库的外键列,而只配置了一个mappyedBy属性,意思是告诉Hibernate,要到多方的一类中的group属性中去找配置信息

@Entity
@Table(name="t_class")
public class Class {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;

  @OneToMany(mappedBy="class")
  private Set<Student> students = new HashSet<Student>();
}

@Entity
@Table(name="t_student")
public class Student {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;

  @ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
  @JoinColumn(name="classid")
  private Class class;
}

单边多对多,双边多对多

单边多对多:一个老师有多个学生,一个学生也有多个老师,但教师类或学生类只有一个类中才包含另外一个类

@Entity
public class Teacher {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;

  @ManyToMany
  @JoinTable( 
    name="t_s",
    joinColumns={@JoinColumn(name="teacher_id")},
    inverseJoinColumns={@JoinColumn(name="student_id")}
  )
  private Set<Student> students = new HashSet<Student>();
}

@Entity
public class Student {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;
}  

双边多对多:在单边多对多的基础上,在另外一个类中添加对应类的集合,并设置mappedBy属性

@Entity
public class Teacher {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;

  @ManyToMany
  @JoinTable( 
    name="t_s",
    joinColumns={@JoinColumn(name="teacher_id")},
    inverseJoinColumns={@JoinColumn(name="student_id")}
  )
  private Set<Student> students = new HashSet<Student>();
}

@Entity
public class Student {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;

  @ManyToMany(mappedBy="students")
  private Set<Teacher> teachers = new HashSet<Teacher>();
}

主键相同的单边一对一,双边一对一

单边一对一:若两个实体类是一对一关系,可以对两个实体类使用相同的主键。例如一个人有且仅有一个身份证,故可以设置为相同主键。此时若在Person类中设置了PrimaryKeyJoinColumn,则在IdCard类中无需设置主键增长策略

@Entity
@Table(name="t_person")
public class Person {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private String id;

  @OneToOne(cascade={CascadeType.ALL})
  @PrimaryKeyJoinColumn
  private IdCard idCard;
}

@Entity
@Table(name="t_idcard")
public class IdCard {
  @Id
  private String id;

  private String name;

  private String sex;
}

双边一对一:在两边均设置PrimaryKeyJoinColumn,并且在利用session.save时,需提前手动设置对方的类Id

@Entity
public class Husband {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  private String name;

  @OneToOne
  @PrimaryKeyJoinColumn
  private Wife wife;
}

@Entity
public class Wife {
  @Id
  private int id;

  private String name;

  @OneToOne
  @PrimaryKeyJoinColumn
  private Husband husband;
}
原文地址:https://www.cnblogs.com/wsy06/p/6819283.html