2012-02-23 61 views
9

我有两个例子,第一个是@OneToOne单向映射和第二个双向。在单向映射中,拥有方表必须包含引用其他表的ID的连接列;那么在双向中它们都必须包含彼此的外键列。但是在使用autogenerate策略生成数据库模式后,两个示例对数据库模式具有相同的效果。单向映射是正常的,但双向示例只包含一个外键列,但它必须涉及对方的外键!@OneToOne单向和双向

单向映射

@Entity 
public class Customer43 { 

@Id 
@GeneratedValue 
private Long id; 
private String firstName; 
private String lastName; 
private String email; 
private String phoneNumber; 
@OneToOne 
@JoinColumn(name = "address_fk") 
private Address43 address; 

// Getters, Setters and Constructors. 
} 

@Entity 
public class Address43 { 

@Id 
@GeneratedValue 
private Long id; 
private String street1; 
private String street2; 
private String city; 
private String state; 
private String zipcode; 
private String country; 

// Getters, Setters and Constructors. 
} 

双向映射

@Entity 
public class Customer44 { 

@Id 
@GeneratedValue 
private Long id; 
private String firstName; 
private String lastName; 
private String email; 
private String phoneNumber; 
@OneToOne 
@JoinColumn(name = "address_fk") 
private Address43 address; 

// Getters, Setters and Constructors. 
} 

@Entity 
public class Address44 { 

@Id 
@GeneratedValue 
private Long id; 
private String street1; 
private String street2; 
private String city; 
private String state; 
private String zipcode; 
private String country; 
@OneToOne(mappedBy = "address") 
private Customer44 customer; 

// Getters, Setters and Constructors. 
} 

为什么数据库模式输出相同的,为什么双向映射的作用类似单向?

回答

19

因为您不了解双向OneToOne如何映射。你不需要两个外键。单一一个足以执行两个表之间的联接,在两个方向上:

select a.* from address a inner join customer c on c.addressId = a.id; 
select c.* from customer c inner join address a on c.addressId = a.id; 

事实上,所述关联是单向或双向的不改变表是如何连接在一起。它只是改变了映射,并允许在两个方向上浏览关联。

在双向关联中,您总是拥有一个拥有的一面(它告诉如何映射关联,使用哪个连接列)以及一个反面,您只需说:我是关联的另一面,由目标实体中的此字段(mappedBy属性值中的字段)映射。

+1

那么,它们的优点或缺点是什么? – 2012-02-25 14:04:59

+9

单向关联的优势在于管理更容易,因为您只需保持一侧。双向关联的优点是您可以在两个方向上导航(获取客户的地址,或获取地址的客户)。 – 2012-02-25 23:21:22

+0

这是否适用于OneToMany和ManyToOne? – 2013-07-26 09:20:40

4

我刚刚在这方面做了一个实验。如果你只是在下面这样做,两个表都将有外键:

@OneToOne 
private Address43 address; 

@OneToOne 
private Customer44 customer; 

现在你不需要做连接。我不确定这是否是一种好的做法。只要确保你没有级联。