当类与类之间创建了关联,就能够方便地从一个对象导航到另外一个或者一组与它关联的对象。例如,对于给定的Order对象,若是想得到与它关联的Customer对象,只要调用以下方法:java
//从Order对象导航到关联的Customer对象 Customer customer=order.getCustomer();
在Order类中,用@ManyToOne注解映射customer属性:数据库
@ManyToOne(targetEntity =Customer.class) @JoinColumn(name="CUSTOMER_ID") private Customer customer;
对于给定的客户,查询该客户的全部订单,只须要调用customer.getOrders()方法。markdown
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()方法。app
在定义Customer类的orders集合属性时,一般把它初始化为集合实现类的一个实例,例如:ide
private Set<order> orders=new HashSet<order>();
这能够提升程序的健壮性,避免应用程序访问取值为null的orders集合的方法而抛出NullPointerException。例如,如下程序访问Customer对象的orders集合,即便orders集合中不包含任何元素,可是调用orders.iterator()方法也不会抛出NullPointerException异常,由于orders集合并不为null:this
Set<Order> orders=customer.getOrders(); Iterator<Order> it=orders.iterator(); while(it.hasNext()){ …… }
如下是Customer.java的源程序。atom
@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<Order> orders = new HashSet<Order>(); //此处省略构造方法,以及id和name属性的访问方法 …… public Set<Order> getOrders(){ return orders; } public void setOrders(Set<Order> orders) { this.orders=orders; } }
对于Customer类的orders属性,因为在CUSTOMERS表中没有直接与orders属性对应的字段,所以不能用@Column注解来映射orders属性,而是要使用@OneToMany注解。@OneToMany注解包括如下属性。spa
在双向关联关系中,能够把一方称为主动方,另外一方称为被动方。主动方会负责维护关联关系,而被动方不负责维护关联关系。被动方用@OneToOne、@OneToMany和@ManyToMany注解来映射,而且设置了mappedBy属性。code
在Customer类与Order类的一对多双向关联关系中,Customer类为“一”的一方,Order类为“多”的一方。Customer类做为“一”的一方,它的@OneToMany注解设置了mappedBy属性,所以Customer类是被动方,而Order类是主动方,负责维护二者之间的关联关系。
所谓维护关联关系,有两层含义:对象