@JoinColumn 详解

一、 

@JoinColumn@Column标记一样,是用于注释表中的字段的。

@JoinColumn@Column相区别的是:
		@JoinColumn注释的是保存表与表之间关系的字段,它要标注在实体属性上。
		@Column标注的是表中不包含表关系的字段。 

相同点: @Column标记一样,name属性是用来标识表中所对应的字段的名称。例如customer表中存在字段addr_id,标识的代码如下所示。 

@OneToOne 
@JoinColumn(name = "addr_id") 
public AddressEO getAddress() { 
   	return address; 
} 

若此时,不设置name的值,则在默认情况下,name的取值遵循以下规则: 

	name=关联表的名称+“_”+ 关联表主键的字段名 

	例如,CustomerEO实体中,如果不指定name的值,默认将对应name=address_id;因为@JoinColumn注释在实体 AddressEO属性上,实体AddressEO对应的表名为“address”;表address的主键是“id”,所以此时对应的默认的字段名称为 “address_id”。 

	//也可以这种形式写
    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
	@JoinColumn(name = "plan_id")  //此表的  plan_id字段   (外健)
    private PricePlan pricePlan;  //外健plan_id 对应的实体属性   此信息会保存到  外健对应的表中
	
	
	提示:此规则只适用于与@OneToOne标记同时使用时。若与@ManyToOne@ManyToMany标记同时使用时,将遵循其他的规则。
	 
	默认情况下,关联的实体的主键一般是用来做外键的。但如果此时不想主键作为外键,则需要设置referencedColumnName属性。例如,将address表中增加一个字段“ref_id”,address表的建表SQL变为以下所示。 

	CREATE TABLE address ( 
	
	id int(20) NOT NULL auto_increment, 
	
	ref_id int int(20) NOT NULL, 
	
	province varchar(50) , 
	
	city varchar(50) , 
	
	postcode varchar(50) , 
	
	detail varchar(50) , 
	
	PRIMARY KEY (id) 
	
	) 

	此时,通过customer表中的“address_id”字段关联的是address表中的“ref_id”,而“ref_id”并不是address表中的主键,则实体中标注如代码下所示。 

@OneToOne 
@JoinColumn(name = "address_id",referencedColumnName="ref_id") 
public AddressEO getAddress() { 
         return address; 
} 

属性referencedColumnName标注的是所关联表中的字段名,若不指定则使用的所关联表的主键字段名作为外键。 

JoinColumn标记不仅能够与@OneToOne使用,也可以@ManyToOne@ManyToMany标记同时使用

二、

1. 一对一
现假设有Person表和Address表,是一对一的关系,在Person中有一个指向Address表主键的字段addressID,所以主控方一定是Person,所谓主控方就是能改变关联关系的一方,Person只要改变addressID就改变了关联关系,所以Person是主控方,所以@JoinColumn写在Person类中

 @OneToOne(cascade=CascadeType.ALL,optional=true)
 @JoinColumn(name="addressID")//注释本表中指向另一个表的外键。
 public Address getAddress() { 
    return address;
}

2.一对多单向
假如现在有Country 表和 Person表,那么一定是Person表中有country_id字段
由于我们是一对多的关系,所以站在一的角度,也就是Country的角度,在Country类中加入@JoinColumn@OneToMany(cascade=CascadeType.ALL) 
@JoinColumn(name="country_id") //注释的是另一个表指向本表的外键。 
public List<Person> getPersons() {
    return persons; 
}
在一对多单向关系中,多的一方(Person)没有注解,一的一方(Country)有注解,如果一的一方不加@JoinColumn指定外键字段的话,Hibernate会自动生成一张中间表Country_PERSON来对Person和Country进行绑定。

3.多对一单向
还是沿用一对多单向的例子,只是反过来,将Country中的注解去掉,挪到Person类中:
@ManyToOne 
@JoinColumn(name="country_id") 
public Country getCountry() { 
    return country; 
}


4.一对多双向

单向关系的缺点还是比较明显的,比如一对多单向,多的那一方没有任何关于另一方的信息,如果我们通过person_id取得一个单独的Person对象,我们没办法知道它属于哪个Country,因为Person类中没有Country对象,多对一单向则是反之。所以正常使用时,一对多双向是最常用的,双方都有彼此的信息。单向变双向,只需在单向的基础上,在Person(多的一方)类中加入多对一的注解:
    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
    @JoinColumn(name = "price_strategy_id")
    private ShiftPriceStrategy priceStrategy;     //  一的一方





5.多对多单向
一般多对多的关系都是用中间表来维护的,假设现在有Person表,Project表,Person_Project表,Person类中的注解:

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "Person_Project",
joinColumns = {@JoinColumn(name = "person_id")},
inverseJoinColumns = {@JoinColumn(name = "project_id")}) 
public List<Project> getProjects() { 
    return project; 
}



  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@JoinColumn是一个JPA注解,它用于指定实体类之间的关联关系。它通常用在外键列上,用于指定关联表的列名和外键列的属性。 在JPA中,实体类之间的关联关系可以是一对一、一对多、多对一或多对多。@JoinColumn注解通常在多对一和一对一关系中使用,用于定义外键列的属性名和关联表的列名。通过使用@JoinColumn注解,我们可以指定关联表中的外键列的名称、类型和是否允许为空。 例如,假设我们有两个实体类:一个是Order(订单),另一个是Customer(客户)。我们想要建立一个多对一的关系,即一个客户可以有多个订单。我们可以在Order实体类中使用@JoinColumn注解来指定外键列和关联表的列名,如下所示: ``` @Entity @Table(name="orders") public class Order { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private int id; @Column(name="order_name") private String orderName; @ManyToOne @JoinColumn(name="customer_id") private Customer customer; //... } ``` 在上面的代码中,@JoinColumn注解指定了外键列的名称为“customer_id”,并且它与Customer实体类的主键列建立关联。这意味着在orders表中,我们将会有一个customer_id列,用于存储Customer实体类的主键值。 总之,@JoinColumn注解是用于定义实体类之间关联关系的重要注解之一,它可以帮助我们指定外键列和关联表的列名,从而实现实体类之间的关联。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值