Hibernate 中 formula屬性的好用處在於 無需在數據庫有真實的列 只須要寫出sql 就能夠建立一個虛擬的列 而後在 Dao層的查詢中使用 ,好比在表 M_Confirmation 中有兩列 Confirmation_Cost 和 Confirmation_Fee 這兩列都允許包含null, 咱們的query要求取得 Confirmation_Cost 和 Confirmation_Fee的和(暫時命名爲Total_Price) 並查出此Total_Price>= 某個前臺傳進來的某個filter的數據 。java
寫成sql 就是 select (confirmation_cost + confirmation+fee) from m_confirmation where (confirmation_cost + confirmation+fee) >= ? ;程序員
這時候建立虛擬列 ,formula後面的部分 會自動跟在hibernate發出的sql中 select後面做爲一列 就比如 select formula from M_confirmation:sql
<property name="totalPrice" formula="((CASE WHEN Confirmation_Cost IS NULL THEN 0 ELSE Confirmation_Cost END) + (CASE WHEN Confirmation_Fee IS NULL THEN 0 ELSE Confirmation_Fee END))" />
注意:數據庫中任何數+null都是null,因此必須用case when處理, 不能 用 nvl由於 nvl只能用於oracle 不符合hibernate移植到任何數據庫的思想。數據庫
而後在 持久化對象中 寫好對應的 totalPrice 屬相:oracle
public class Confirmation extends ConfirmationBase implements BasicModel { private BigDecimal totalPrice; public BigDecimal getTotalPrice() { return totalPrice; } public void setTotalPrice(BigDecimal totalPrice) { this.totalPrice = totalPrice; } @Override public String toString() { return ToStringBuilder.reflectionToString(this, TafToStringStyles.PERSISTENCE_TOSTRING_STYLE); }
這樣 你就能夠靈活使用數據庫中任何列 排列組合成一些虛擬列 來作查詢了:ide
BigDecimal bpsPrice = filter.getBpsPrice(); DetachedCriteria criteria = DetachedCriteria.forClass(Confirmation.class); if (bpsPrice != null) { criteria.add(Restrictions.ge("totalPrice", bpsPrice)); } return getHibernateTemplate().findByCriteria(criteria);
這就是屬性中 formula屬性的用處,最後再提醒一下 formula=配置的內容會自動跟在發出的sql的 select後面做爲一列 ,因此不少人 後面寫出完整的 select 最後拼出的sql是錯誤的。這樣工做中方便更加區分邏輯 加快代碼可讀性 對數據庫列的數量也沒有太多影響,ui
固然你也能夠在 Criteria中直接寫 以下:this
BigDecimal bpsPrice = filter.getBpsPrice(); DetachedCriteria criteria = DetachedCriteria.forClass(Confirmation.class); if (bpsPrice != null) { criteria .add(Restrictions.sqlRestriction("((CASE WHEN Confirmation_Cost IS NULL THEN 0 ELSE Confirmation_Cost END) + (CASE WHEN Confirmation_Fee IS NULL THEN 0 ELSE Confirmation_Fee END)) >=") + bpsPrice ); } return getHibernateTemplate().findByCriteria(criteria);
可是這樣的寫法嚴格的公司沒法經過代碼審覈,由於不方便閱讀 沒有作到好的分層 假設新來的程序員若是改了表的列名而沒有看到你寫的這句會出現bug 通常這樣寫會被打回來重新改spa
若是你公司廣泛使用Native sql 或者 HQL來作查詢的標準 那這種formula配置就失去做用 沒有用處了 徹底能夠用一些常量替代
hibernate