@JoinColumn详解

标签: JoinColumn
12人阅读 评论(0) 收藏 举报
分类:
@JoinColumn 注解的作用:用来指定与所操作实体或实体集合相关联的数据库表中的列字段。
由于 @OneToOne(一对一)、@OneToMany(一对多)、@ManyToOne(多对一)、@ManyToMany(多对多) 等注解只能确定实体之间几对几的关联关系,它们并不能指定与实体相对应的数据库表中的关联字段,因此,需要与 @JoinColumn 注解来配合使用。
在此,我们以员工、地址、部门、角色四者之间的关联关系为例进行详细介绍,假设:
1.一个员工只能有一个地址,同样的,一个地址也只属于一个员工;
2.一个员工只能属于一个部门,但是一个部门可以包含有多个员工;
3.一个员工可以拥有多个角色,同样的,一个角色也可以属于多个员工。

@OneToOne(一对一)

@OneToOne 用来表示类似于以上员工与地址之间的一对一的关系,在员工表中会有一个指向地址表主键的字段address_id,所以主控方(指能够主动改变关联关系的一方)一定是员工,因为,只要改变员工表的address_id就改变了员工与地址之间的关联关系,所以@JoinColumn要写在员工实体类Employee上,自然而然地,地址就是被控方了。
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "address_id")
private Address address;
我们也可以不写@JoinColumn,Hibernate会自动在员工表生成关联字段,字段默认的命名规则:被控方类名_被控方主键,如:address_id。
如果两张表是以主键关联的,比如员工表主键是employee_id,地址表主键是address_id,可以使用如下注解:
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "address_id")
private Address address;

@OneToMany(一对多)

在分析员工与部门之间的关系时,一个员工只能属于一个部门,但是一个部门可以包含有多个员工,如果我们站在部门的角度来看,部门与员工之间就是一对多的关系,在部门实体类 Department 上添加如下注解:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "department_id")
private List<Employee> employees;
我们也可以不写@JoinColumn,Hibernate会自动生成一张中间表来对员工和部门进行绑定,表名默认的命名规则:一的表名_一实体类中关联多的属性名,例如,部门表名为 tbl_department ,部门实体中关联的员工集合属性名为 employees ,则生成的中间表名为:tbl_department_employees。
通常并不推荐让Hibernate自动去自动生成中间表,而是使用@JoinTable注解来指定中间表:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
/**
* joinColumns 用来指定中间表中关联自己ID的字段 
* inverseJoinColumns 用来指定中间表中关联对方ID的字段
*/
@JoinTable(name = "tbl_employee_department", joinColumns = {
@JoinColumn(name = "department_id") }, inverseJoinColumns = { @JoinColumn(name = "employee_id") })
private List<Employee> employees;

@ManyToOne(多对一)

如果我们站在员工的角度来看员工与部门之间的关系时,二者之间就变成了多对一的关系,在员工实体类 Employee 上添加如下注解:
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "department_id")
private Department department;

@ManyToMany(多对多)

类似员工与角色之间的关系,一个员工可以拥有多个角色,一个角色也可以属于多个员工,员工与角色之间就是多对多的关系。通常这种多对多关系都是通过创建中间表来进行关联处理,并使用@JoinTable注解来指定。
一个员工可以拥有多个角色,在员工实体类中添加如下注解:
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "tbl_employee_role", joinColumns = { @JoinColumn(name = "employee_id") }, inverseJoinColumns = {
@JoinColumn(name = "role_id") })
private List<Role> roles;
一个角色可以属于多个员工,在角色实体类中添加如下注解:
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "tbl_employee_role", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = {
@JoinColumn(name = "employee_id") })
private List<Employee> employees;
定义好的员工、地址、部门、角色四个实体类代码如下:
员工实体类。
@Entity
@Table(name = "tbl_employee") // 指定关联的数据库的表名
public class Employee {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id; // 主键ID

	private String name; // 姓名

	@DateTimeFormat(pattern = "yyyy-MM-dd")
	private LocalDate birthday; // 生日

	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinColumn(name = "address_id")
	// @PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "address_id")
	private Address address; // 地址

	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@JoinColumn(name = "department_id")
	private Department department; // 部门

	@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinTable(name = "tbl_employee_role", joinColumns = { @JoinColumn(name = "employee_id") }, inverseJoinColumns = {
			@JoinColumn(name = "role_id") })
	private List<Role> roles; // 角色

	// 此处省略get和set方法
}
地址实体类。
@Entity
@Table(name = "tbl_address")
public class Address {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id; // 主键ID

	private String province; // 省

	private String city; // 市

	private String district; // 区

	private String address; // 详细地址

	// 此处省略get和set方法

}
部门实体类。
@Entity
@Table(name = "tbl_department")
public class Department {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id; // 主键ID

	private String name; // 部门名称

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@JoinColumn(name = "department_id")
	/**
	 * joinColumns 用来指定中间表中关联自己ID的字段 inverseJoinColumns 用来指定中间表中关联对方ID的字段
	 */
	// @JoinTable(name = "tbl_employee_department", joinColumns = {
	// 		@JoinColumn(name = "department_id") }, inverseJoinColumns = { @JoinColumn(name = "employee_id") })
	private List<Employee> employees; // 部门员工

	// 此处省略get和set方法
}
角色实体类。
@Entity
@Table(name = "tbl_role")
public class Role {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id; // 主键ID

	private String name; // 角色名称

	@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinTable(name = "tbl_employee_role", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = {
			@JoinColumn(name = "employee_id") })
	private List<Employee> employees; // 拥有角色的员工

	// 此处省略get和set方法

}

查看评论

@JoinColumn 详解

在address中没有特殊的注解。 在Person中对应到数据库里面就有一个指向Address的外键. 我们也可以增加注释指定外键的列的名字,如下: @OneToOne(cascade=Casc...
  • maoyeqiu
  • maoyeqiu
  • 2015-11-16 15:58:30
  • 1467

JavaWeb后台JoinColumn的用法理解

今天研究了下JoinColumn的用法,可能有些错误,先整理一下. 用法实例: @ManyToOne(targetEntity = Staff.class) @JoinColumn(name...
  • huozengguang
  • huozengguang
  • 2016-11-09 11:52:47
  • 1251

@JoinTable和@JoinColumn

默认情况下,JPA持续性提供程序在映射多对多关联(或在单向的一对多关联中)的拥有方上的实体关联时使用一个连接表。连接表名称及其列名均在默认情况下指定,且JPA 持续性提供程序假设:在关系的拥有方上的实...
  • a468903507
  • a468903507
  • 2014-02-26 11:18:45
  • 3033

@JoinColumn解释

@JoinColumn与@Column标记一样,是用于注释表中的字段的。它的属性与@Column属性有很多相同之处,这里就不详细讲述。请读者参阅5.2.2小节中有关@Column属性的部分。  ...
  • z69183787
  • z69183787
  • 2014-02-27 12:48:22
  • 18748

Hibernate中,mappedBy和注解@JoinColumn的对比

一对多 @JoinColumn(name=“FK_name”) 在多的一方的作用是为了指定外键字段的名称,就算没有ManyToOne也会自己创建外键 在一的一方是为了指定外表指向本表的外键,如果...
  • u014685516
  • u014685516
  • 2017-03-05 12:27:25
  • 1366

@JoinColumn 匹配关联多个字段

两张表结构如下 TABLE_A: ID, COLA1, COLA2 TABLE_B: ID, A_ID, COLB1, COLB2 A和B是一对多的关系。 我在...
  • kunga0814
  • kunga0814
  • 2012-05-02 15:55:26
  • 14948

JoinColumn详解

在address中没有特殊的注解。 在Person中对应到数据库里面就有一个指向Address的外键. 我们也可以增加注释指定外键的列的名字,如下: @OneToOne(cascad...
  • liujianwd
  • liujianwd
  • 2017-07-21 10:36:31
  • 101

Hibernate @OneToMany的mappedBy和@JoinColumn总结

在一对多和多对一双向关联时: @OneToMany(cascade=ALL) // @JoinColumn(name="s_class") //如果一端设置了@JoinColumn,那么它...
  • tingyingg
  • tingyingg
  • 2014-04-17 20:52:16
  • 2486

@ManyToOne 和@oneToMany中@@JoinColumn的区别

@ManyToOne中是在本类对应的数据库表中生成 例如 [c-sharp] view plaincopy @Entity   @Table...
  • wengzhiyou001
  • wengzhiyou001
  • 2014-10-28 13:33:17
  • 2320

hibernate annotation 之mappedBy 与 @JoinColumn区别

1.一对多的映射(one-to-many) @Entity @Table(name="t_classroom") public class ClassRoom { private int i...
  • qiuzhi__ke
  • qiuzhi__ke
  • 2016-02-25 17:28:31
  • 3227
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 128万+
    积分: 1万+
    排名: 1315
    博客专栏
    最新评论