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"));
------
---
沒有留言:
張貼留言