並非持久化類的全部屬性都直接和表的字段匹配,持久化類的有些屬性的值必須在運行時經過計算才能得出來,這種屬性稱爲派生屬性。下面介紹利用Hibernate的@Formula註解來映射派生屬性。java
@Formula註解用來設置一個SQL表達式,Hibernate將根據它來計算出派生屬性的值。數據庫
下面以Customer類的totalPrice屬性爲例,介紹@Formula註解的用法。Customer類的totalPrice屬性表示客戶的全部訂單的價格總和,它的取值爲與Customer對象關聯的全部Order對象的price屬性值的和。在CUSTOMERS表中沒有對應的TOTAL_PRICE字段。在Customer類中映射totalPrice屬性的代碼以下:markdown
@Formula("(select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=ID)") public Double getTotalPrice(){ return this.totalPrice; }
當Hibernate從數據庫中查詢Customer對象時,在select語句中會包含以上用於計算totalPrice派生屬性的子查詢語句:ide
select ID,NAME, SEX, `CUSTOMER DESCRIPTION`, (select sum(o.PRICE) from ORDERS o where o.CUSTOMER_ID=1) from CUSTOMERS;
若是子查詢語句的查詢結果爲空,即客戶沒有任何訂單時,Hibernate會把totalPrice屬性賦值爲null,若是totalPrice屬性爲double基本類型,會拋出如下異常:函數
org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of mypack.Customer.totalPrice
爲了不以上異常,應該把totalPrice屬性定義爲Double包裝類型。
@Formula註解指定一個SQL表達式,該表達式能夠引用表的字段,調用SQL函數或者包含子查詢語句。例如,表示客戶購買單項商品信息的LineItem類中有一個unitPrice屬性,取值爲:this
商品單價(BASE_PRICE) * 購買數量(QUANTITY)
而在LINEITEMS表中沒有對應的UNIT_PRICE字段,只有BASE_PRICE和QUANTITY字段,能夠經過如下方式映射unitPrice屬性:atom
@Formula("BASE_PRICE*QUANTITY") public Double getUnitPrice(){ return this.unitPrice; }