一对多
映射关系是在实体类中定义,如一个老师对应多个学生(关系是一对多),则在老师的实体类中定义一个学生的集合,如下
@OneToMany(targetEntity = Student.class) // 当前实体类一对多到哪个实体类上,主表对应从表
@JoinColumn(name = "teacher_id", referencedColumnName = "id") // name为子表的外键,referencedColumnName为主表的哪个字段对应子表的外键
private Set<Student> students = new HashSet<Student>();
反之,多个学生对应一个老师,则是多对一,就需要在Student的实体类中定义关联关系,如下
@ManyToOne(targetEntity = Teacher.class) // 当前实体类多对一到哪个实体类上,从表对应主表
@JoinColumn(name = "teacher_id", referencedColumnName = "id") // name为从表的外键,referencedColumnName为主表的哪个字段对应从表的外键
private Teacher teacher;
当然,主表也可以放弃外键维护权,使用从表实体类定义的关联关系
@OneToMany(mappedBy = "teacher", cascade = CascadeType.ALL) // mappedBy对方配置关系的属性名称,CascadeType是级联操作类型
private Set<Student> linkmans = new HashSet<Student>();
多对多
场景:一个用户对应多个角色(user表),一个角色也对应多个用户(role表),他们之间有一个中间表(user_role_map表)
一个用户对应多个角色
@ManyToMany(targetEntity = Role.class, cascade = CascadeType.ALL)
@JoinTable(name = "user_role_map",
// joinColumns,当前对象在中间表中的外键字段名称和外键对应的当前表的字段名称
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "user_id")},
// inverseJoinColumns,对方对象在中间表中的外键字段名称和外键对应的当前表的字段名称
inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "role_id")}
)
private Set<Role> roles = new HashSet<Role>();
一个角色也对应多个用户
@ManyToMany(targetEntity = User.class, cascade = CascadeType.ALL)
@JoinTable(name = "user_role_map",
// joinColumns,当前对象在中间表中的外键字段名称和外键对应的当前表的字段名称
joinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "role_id")},
// inverseJoinColumns,对方对象在中间表中的外键字段名称和外键对应的当前表的字段名称
inverseJoinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "user_id")}
)
private Set<User> users = new HashSet<User>();
其中一个也可以放弃外键维护权力,使用对方提供好的关联关系,一般是被动的一方放弃,这里我们在角色表的实体类放弃主键维护权
@ManyToMany(mappedBy = "roles", cascade = CascadeType.ALL)
private Set<User> users = new HashSet<User>();