JPA @NamedQuery 查詢範例
在之前的實例中,我們知道採用HQL語法執行查詢的一般用法如下:
public ProductItem findProductItemBySku(String sku) { String hql = "from ProductItem where sku=:sku "; // 取得 EntityManager EntityManager em = entityManagerFactory.createEntityManager(); Query query = em.createQuery(hql); // 建立查詢語法 query.setParameter("sku", sku); // 填入查詢條件 // 依照產品編號 (SKU) 找到對應的產品基本資料 ProductItem result = (ProductItem) query.getSingleResult(); return result; } |
Hql 查詢語句分別寫在不同 method 的作法是常見也容易理解的,基本上也沒有甚麼大問題,但hql 語法分散在各個不同的方法裡容易造成維護上的困難,尤其是 BO 屬性被更動過的時候,開發者調整了 BO 的屬性也需要同步調整對應的 hql 語法,如果沒有同步調整就容易發生疏漏,沒被同步修正的部分就可能會發生狀況。
關於這個問題,一般的解決方案會把hql 查詢語句從 method 層級提升到 class層級去宣告,如此一來,日後要修改時,只要修正物件層級的變數即可,如此便可減少這類的問題發生;
更好的作法是,採用JPA提供的 @NamedQuery annotation去宣告 hql 查詢語句,在 BO 當中宣告hql 查詢語句,日後如果要調整 BO 當中的屬性宣告時,開發人員僅需調整該 BO 的屬性與hql 查詢語句即可,完全不需要調閱其他的程式碼,就可以完成調整動作,因此,可以有效降地維護成本。
@NamedQuery annotation宣告方式與應用範例如下:
// 宣告 @NameQuery 的範例程式 @NamedQuery(name="findProductItemBySku", query="from ProductItem where sku=:sku ") @Entity public class ProductItem { … } |
// 引用 @NameQuery 的範例程式 public ProductItem findProductItemBySku(String sku) { ProductItem result = null; // 取得 EntityManager EntityManager em = entityManagerFactory.createEntityManager(); try { // 依照產品編號 (SKU) 找到對應的產品基本資料 result = (ProductItem) em.createNamedQuery("findProductItemBySku").setParameter("sku", sku).getSingleResult(); } catch (NoResultException err) { } finally { em.close(); } return result; } |
如果開發者要在同一個 BO 當中宣告多組 @NameQuery 時,請利用@NamedQueries annotation 加以宣告,範例如下:
// 宣告多組 @NameQuery 的範例程式 @NamedQueries({ @NamedQuery(name="findProductItemBySku", query="from ProductItem where sku=:sku "), @NamedQuery(name="findProductItemByName", query="from ProductItem where name=:name ") }) @Entity public class ProductItem { … } |
相關資訊:Java Persistence API
沒有留言:
張貼留言