select * from book order by length(title) asc;在 Hibernate Criteria 裡要怎麼使用呢?在 Criteria、Property 與 Projections 裡怎麼也找不到相關的 API,最後 Google 才說,要用 @Formula 建立虛擬欄位。
Hibernate 提供的 @Formula 有兩種用途,第一是使用資料庫的運算,而非 JVM,第二是虛擬欄位,也就是不存在資料庫中的欄位,由其他欄位計算產生出來的結果。
@Entity @SuppressWarnings("serial") public class Book implements Serializable { private Integer uid; private String title; private int titleLength; private double price; private double priceWithTax; @Id @GeneratedValue(strategy = GenerationType.AUTO) public Integer getUid() { return this.uid; } public void setUid(Integer uid) { this.uid = uid; } @Column public String getTitle() { return this.title; } public void setTitle(String title) { this.title = title; } @Formula("length(title)") public int getTitleLength() { return this.titleLength; } // @Formula 為唯讀欄位 private void setTitleLength(int titleLength) { this.titleLength = titleLength; } @Column public double getPrice() { return this.price; } public void setPrice(double price) { this.price = price; } @Formula("price * 1.05") public double getPriceWithTax() { return this.priceWithTax; } // @Formula 為唯讀欄位 private void setPriceWithTax(double priceWithTax) { this.priceWithTax = priceWithTax; } }以上範例中的 uid、title 與 price 都是傳統的實際欄位對應,而 titleLength 則是虛擬欄位,由 SQL 的 length function 產生,另外 priceWithTax 則是借重資料庫的計算能力,當然也可以交給 JVM 去算。
@Transient public double getPriceWithTax() { return this.price * 1.05; }@Formula 可以很複雜到用 Subselect 都沒問題,只是要擔心執行效能,由於每次撈資料都會執行,即使在程式中沒用到這個虛擬欄位,透過 Hibernate 從資料庫裡出來時就會跑一次。
最後還是說一下一開始問題的解答,雖然不值得一提。
Criteria c = this.getSession().createCriteria(Book.class); c.addOrder(Order.asc("titleLength"));---
---
---
沒有留言:
張貼留言