hibernate注解的关联关系映射,分为2种,即单向关联映射和双向关联映射,它们最大的区别就是在查询数据时,单向关联只能通过一边进行查询,而双向关联两边都可以进行查询。
单向关联是指只在一方加上注解,
双向关联是指双方都加上注解。这里主要记录双向关联。
1. 一对一关联:
如有2张表,公民表Person和身份证表IdCard
一方(IdCard):
@OneToOne(fetch=FetchType.LAZY,//延迟加载
targetEntity=IdCards.class,//目标对象
mappedBy="person",//指定由哪边维护关系(在这指有Person表维护,‘person’指IdCards标中关联的Person对象)
cascade=CascadeType.ALL)
另一方(Person):
@OneToOne(fetch=FetchType.LAZY,
targetEntity=Person.class)//维护关系表
@JoinColumn(name="personId",referencedColumnName="personId",unique=true)
具体如下:
- @Entity
- @Table(name = "tb_person")
- public class Person implements Serializable {
-
- private static final long serialVersionUID = 576770011136181361L;
-
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private Long personId;
- <span style="white-space:pre"> </span>@OneToOne(fetch=FetchType.LAZY,targetEntity=IdCards.class,mappedBy="person",cascade=CascadeType.ALL)
- <span style="white-space:pre"> </span>private IdCard idcard;
- @Entity
- @Table(name = "tb_idcard")
- public class Idcard implements Serializable {
-
- private static final long serialVersionUID = 576770011136181369L;
-
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private Long idcardId;
- <span style="white-space:pre"> </span>@OneToOne(fetch=FetchType.LAZY,
- <span style="white-space:pre"> </span>targetEntity=Person.class)
- <span style="white-space:pre"> </span>@JoinColumn(name="personId",referencedColumnName="personId",unique=true)
- <span style="white-space:pre"> </span>private Person person;
2. 一对多关系:
一方:
@OneToMany(fetch=FetchType.LAZY,
targetEntity=User.class,
cascade=CascadeType.ALL,
orphanRemoval=true,//孤儿删除
mappedBy="department")
- cascade=CascadeType.ALL,,即交由多的一方控制;
多方:
@ManyToOne(fetch = FetchType.LAZY,targetEntity = Department.class)@JoinColumn(name = "departmentId",referencedColumnName="departmentId")- <span style="white-space:pre"> </span>如:一个用户只能属于一个部门,一个部门里可以有很多用户,其注解如下,
- 部门实体类:
- @Entity
- @Table(name = "tb_department")
- public class Department implements Serializable {
-
- private static final long serialVersionUID = -3489189232910430049L;
-
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private Long departmentId;
-
- private String name;
-
- private String description;
- <span style="white-space:pre"> </span>@OneToMany(fetch=FetchType.LAZY,targetEntity=User.class,cascade=CascadeType.ALL,orphanRemoval=true,mappedBy="department")
- <span style="white-space:pre"> </span>private Set<User> users;
- ........
- }
- 用户实体类:
- @Entity
- @Table(name="tb_user")
- public class User implements Serializable {
-
- private static final long serialVersionUID = 576770011136181361L;
-
- @Id
- @GeneratedValue(strategy=GenerationType.AUTO)
- private Long userId;
-
- <span style="white-space:pre"> </span>@ManyToOne(fetch = FetchType.LAZY,targetEntity = Department.class)
- <span style="white-space:pre"> </span>@JoinColumn(name = "departmentId",referencedColumnName="departmentId")
- <span style="white-space:pre"> </span>private Department department;
-
- private String loginName;
- ........
- ........
}
2. 多对多关系: 多方:
@ManyToMany(fetch=FetchType.LAZY,targetEntity=Role.class)@JoinTable(name = "tb_user_role", joinColumns = @JoinColumn(name = "userId",referencedColumnName="userId") , inverseJoinColumns = @JoinColumn(name = "roleId",referencedColumnName="roleId"))
其中“tb_user_role”是两者的关系表,由两者的主键ID组成。通过@JoinColumn(name = "userId")指定在关系表中的字段名。
另一个多方:
@ManyToMany(fetch = FetchType.LAZY, targetEntity = User.class, cascade = CascadeType.ALL, mappedBy = "roles")
- joinColumns :指主表,inverseJoinColumns :指匹配表
即user-->role,则user是主表,role是匹配表
如:一个用户可以有多个角色,一个角色可以适用于多个用户。
- 用户实体类:
-
- @Entity
- @Table(name="tb_user")
- public class User implements Serializable {
-
- private static final long serialVersionUID = 576770011136181361L;
-
- @Id
- @GeneratedValue(strategy=GenerationType.AUTO)
- private Long userId;
-
- private String loginName;
-
- private String name;
-
- private String gender;
-
- private String phone;
-
- private String email;
-
- private String description;
-
- @ManyToMany(fetch=FetchType.LAZY,targetEntity=Role.class)
- <span style="white-space:pre"> </span>@JoinTable(name = "tb_user_role", joinColumns = @JoinColumn(name = "userId",referencedColumnName="userId") ,
- <span style="white-space:pre"> </span>inverseJoinColumns = @JoinColumn(name = "roleId",referencedColumnName="roleId"))
- <span style="white-space:pre"> </span>private Set<Role> roles = new HashSet<Role>();
- 角色实体类:
-
- @Entity
- @Table(name = "tb_role")
- public class Role implements Serializable {
-
- private static final long serialVersionUID = -7625883839295666830L;
-
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private Long roleId;
-
- private String name;
-
- private String description;
-
- @ManyToMany(fetch = FetchType.LAZY, targetEntity = User.class, cascade = CascadeType.ALL, mappedBy = "roles")
- <span style="white-space:pre"> </span>private Set<User> users = new HashSet<User>();
- .....
- .....
- }
2. 自连接关系:
自连接一方:
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Department.class)
@JoinColumn(name = "parentId",referencedColumnName="departmentId")
自连接多方:
@OneToMany(fetch=FetchType.LAZY,targetEntity=Department.class,cascade=CascadeType.ALL,orphanRemoval=true,mappedBy="parent")
@OrderBy("departmentId ASC")
因为是自连接,在一个表里操作,表中要增加一个父类id,用户建立连接。
如:部门管理,一个部门可以有很多个下级部门,但是一个上级部门只能有一个上级部门,这时需要建立自连接。
- 部门实体类::
-
- @Entity
- @Table(name = "tb_department")
- public class Department implements Serializable {
-
- private static final long serialVersionUID = -3489189232910430049L;
-
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private Long departmentId;
-
- private String name;
-
- private String description;
-
- <span style="white-space:pre"> </span>@ManyToOne(fetch = FetchType.LAZY, targetEntity = Department.class)
- <span style="white-space:pre"> </span>@JoinColumn(name = "parentId",referencedColumnName="departmentId")
- <span style="white-space:pre"> </span>private Department parent;
-
-
- <span style="white-space:pre"> </span>@OneToMany(fetch=FetchType.LAZY,targetEntity=Department.class,cascade=CascadeType.ALL,orphanRemoval=true,mappedBy="parent")
- <span style="white-space:pre"> </span>@OrderBy("departmentId ASC")
- <span style="white-space:pre"> </span>private Set<Department> children = new HashSet<Department>();
- <span style="white-space:pre"> </span>....
- .....
- }