當類與類之間創建了關聯,就能夠方便地從一個對象導航到另外一個或者一組與它關聯的對象。例如,對於給定的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類是主動方,負責維護二者之間的關聯關係。
所謂維護關聯關係,有兩層含義:對象