:雙向一對多關系,一是關系維護端(owner side),多是關系被維護端(inverse side)。在關系被維護端需要通過@JoinColumn建立外鍵列指向關系維護端的主鍵列。
publicclass Order implements Serializable { PRivateSet orderItems = new HashSet(); 。。。。 @OneToMany(mappedBy=”order”,cascade = CascadeType.ALL, fetch = FetchType.LAZY) @OrderBy(value = “id ASC”) public Set getOrderItems() { returnorderItems; } }
publicclass OrderItem implements Serializable { private Order order; 。。。。 @ManyToOne(cascade=CascadeType.REFRESH,optional=false) @JoinColumn(name = “order_id”) public Order getOrder() { returnorder; } } @OrderBy(value = “id ASC”) 指明加載OrderItem 時按id 的升序排序
@OneToMany的屬性: 1>targetEntity 定義關系類的類型,默認是該成員屬性對應的類類型,所以通常不需要提供定義。
2>mappedBy 定義類之間的雙向關系。如果類之間是單向關系,不需要提供定義,如果類和類之間形成雙向關系,我們就需要使用這個屬性進行定義,否則可能引起數據一致性的問題。 該屬性的值是“多”方class里的“一”方的變量名
3>cascade 該屬性定義類和類之間的級聯關系。定義的級聯關系將被容器視為對當前類對象及其關聯類對象采取相同的操作,而且這種關系是遞歸調用的。舉個例子:Order 和OrderItem有級聯關系,那么刪除Order時將同時刪除它所對應的OrderItem對象。而如果OrderItem還和其他的對象之間有級聯關系,那么這樣的操作會一直遞歸執行下去。
cascade的值只能從CascadeType.PERSIST(級聯新建)、CascadeType.REMOVE(級聯刪除)、CascadeType.REFRESH(級聯刷新)、CascadeType.MERGE(級聯更新)中選擇一個或多個。還有一個選擇是使用CascadeType.ALL,表示選擇全部四項。
4>fatch 可選擇項包括:FetchType.EAGER和FetchType.LAZY。前者表示關系類(本例是OrderItem 類)在主類(本例是Order類)加載的時候同時加載,后者表示關系類在被訪問時才加載。默認值是FetchType.LAZY。
@JoinColumn(name = “order_id”)注釋指定OrderItem映射表的order_id列作為外鍵與Order 映射表的主鍵列關聯。
@ManyToOne:指明OrderItem和Order之間為多對一關系。
@ManyToOne注釋有四個屬性:targetEntity、cascade、fetch 和optional,前三個屬性的具體含義和@OneToMany的同名屬性相同,但@ManyToOne的fetch 屬性默認值是FetchType.EAGER。
optional屬性是定義該關聯類是否必須存在,值為false 時,關聯類雙方都必須存在,如果關系被維護端不存在,查詢的結果為null。值為true 時, 關系被維護端可以不存在,查詢的結果仍然會返回關系維護端,在關系維護端中指向關系被維護端的屬性為null。optional屬性的默認值是true。optional 屬性實際上指定關聯類與被關聯類的join 查詢關系,如optional=false 時join 查詢關系為inner join, optional=true 時join 查詢關系為left join。下面代碼片斷解釋如下:
有一點需要強調:當業務方法需要把一個實體Bean作為參數返回給客戶端時,除了實體Bean本身需要實現Serializable 接口之外,如果關聯類(OrderItem)是延遲加載,還需在返回實體Bean之前通過訪問關聯類的方式加載關聯類(見下例)。否則在客戶端訪問關聯類時將會拋出加載例外。 public Order getOrderByID(Integer orderid) { Order order = em.find(Order.class, orderid); //!!!!!因為是延遲加載,通過執行size()這種方式獲取訂單下的所有訂單項 order.getOrderItems().size(); return order; }
另外不管是否延遲加載,通過join fetch 關聯語句都可顯式加載關聯類,如下例:
public List getAllOrder() { Query query = em.createQuery("select DISTINCT o from Order o innerjoin fetch o.orderItems order by o.orderid”); List result = query.getResultList(); return result; }
新聞熱點
疑難解答