|
本文参考《精通JPA与Hibernate:Java对象持久化技术详解》,作者:孙卫琴,清华大学出版社出版
当类与类之间建立了关联,就可以方便地从一个对象导航到另一个或者一组与它关联的对象。例如,对于给定的Order对象,如果想获得与它关联的Customer对象,只要调用如下方法: //从Order对象导航到关联的Customer对象
Customer customer=order.getCustomer(); |
在Order类中,用@ManyToOne注解映射customer属性:
@ManyToOne(targetEntity =Customer.class)
@JoinColumn(name="CUSTOMER_ID")
private Customer customer; |
对于给定的客户,查询该客户的所有订单,只需要调用customer.getOrders()方法。
Hibernate要求在持久化类中定义集合类属性时,必须把属性声明为接口类型,如java.util.Set、java.util.Map和java.util.List。声明为接口可以提高持久化类的透明性,当Hibernate调用setOrders(Set orders)方法时,传递的参数是Hibernate自定义的实现该接口的类的实例。如果把orders声明为java.util.HashSet类型(它是java.util.Set接口的一个实现类),就强迫Hibernate只能把HashSet类的实例传给setOrders()方法。
在定义Customer类的orders集合属性时,通常把它初始化为集合实现类的一个实例,例如:
private Set orders=new HashSet(); |
这可以提高程序的健壮性,避免应用程序访问取值为null的orders集合的方法而抛出NullPointerException。例如,以下程序访问Customer对象的orders集合,即使orders集合中不包含任何元素,但是调用orders.iterator()方法也不会抛出NullPointerException异常,因为orders集合并不为null:
Set orders=customer.getOrders();
Iterator it=orders.iterator();
while(it.hasNext()){
……
} |
以下是Customer.java的源程序。
@Entity@Table(name="CUSTOMERS")
public class Customer implements java.io.Serializable {
@Id
@GeneratedValue(generator="increment")
@GenericGenerator(name="increment", strategy = "increment")
@Column(name="ID")
private Long id;
@Column(name="NAME")
private String name;
@OneToMany(mappedBy="customer",
targetEntity=Order.class,
cascade=CascadeType.ALL)
private Set orders = new HashSet();
//此处省略构造方法,以及id和name属性的访问方法
……
public Set getOrders(){
return orders;
}
public void setOrders(Set orders) {
this.orders=orders;
}
} |
对于Customer类的orders属性,由于在CUSTOMERS表中没有直接与orders属性对应的字段,因此不能用@Column注解来映射orders属性,而是要使用@OneToMany注解。@OneToMany注解包括以下属性。 - targetEntity属性:指定orders集合中存放的是Order对象。
- mappedBy属性:指定Order类中的customer属性引用所关联的Customer对象。
- cascade:当取值为CascadeType.ALL,表示会执行级联保存、更新和删除等操作。
在双向关联关系中,可以把一方称为主动方,另一方称为被动方。主动方会负责维护关联关系,而被动方不负责维护关联关系。被动方用@OneToOne、@OneToMany和@ManyToMany注解来映射,并且设置了mappedBy属性。
在Customer类与Order类的一对多双向关联关系中,Customer类为“一”的一方,Order类为“多”的一方。Customer类作为“一”的一方,它的@OneToMany注解设置了mappedBy属性,因此Customer类是被动方,而Order类是主动方,负责维护两者之间的关联关系。
所谓维护关联关系,有两层含义:- (1)指在数据库中,主动方Order类对应的ORDERS表的外键参照CUSTOMERS表。假如Customer类的@OneToMany注解没有使用mappeBy属性,那么Customer类变成主动方,需要维护与Order类的关联关系,此时需要创建额外的CUSTOMER_ORDER连接表。
- (2)Hibernate会根据主动方的持久化对象的关联关系的变化去同步更新数据库。
程序猿的技术大观园:www.javathinker.net
[这个贴子最后由 admin 在 2021-10-09 10:45:24 重新编辑]
|
|