摘要:的離線查詢對象用起來的確很是方便,但是其有一個缺陷通過條件表達式方法添加的條件會累加其實就是存入中的這樣如果要執行不同的查詢需要不同的查詢條件時就需要分別創建不同的離線查詢對象。
背景hibernate的離線查詢對象DetachedCriteria用起來的確很是方便,但是其有一個缺陷:通過·add(條件表達式)方法添加的條件, 會累加, 其實就是存入list中的, 這樣如果要執行不同的查詢, 需要不同的查詢條件時, 就需要分別創建不同的離線查詢對象。
今天碰到的一個需求中, 一個Action中對同一張表連續查了三次, 每一次用了不同的離線查詢對象. 感覺優點麻煩, 就想看看有沒有對應的方法清除上次用過不想用的條件表達式. 結果發現并沒有, 于是, 就自己通過暴力反射的技術, 寫了一個小工具方法, 可以實現清除指定離線查詢對象中的所有條件表達式。
通常我們在使用離線查詢技術時, 會這么使用.
如查詢BaseDict對象對應的表中dictTypeCode=006的記錄.
// 創建離線查詢對象 DetachedCriteria dc = DetachedCriteria.forClass(BaseDict.class); // 設置查詢條件 dc.add(Restrictions.eq("dictTypeCode", "006")); // 利用hibernateTemplate模板根據離線對象查詢數據 Listlist = (List ) getHibernateTemplate().findByCriteria(dc);
然而, 當我們需要再次查詢BaseDict中dictTypeCode=009的記錄時, 需要重新創建一個新的DetachedCriteria. 否則, 會將上次dictTypeCode=006的條件合并起來. 看下圖:
源碼分析DetachedCriteria dc = DetachedCriteria.forClass(BaseDict.class);
==> 調用構造
DetachedCriteria dc = DetachedCriteria.forClass(clazz.getName); // 通過類名構建對象
==>
CriteriaImpl(entityName, ...) // 創建Criteria的實現類
注意: 這是實現類會在離線查詢對象dc名為"impl"屬性中持有.
進入CriteriaImpl會發現, 原來我們add的所有查詢條件會保存在一個叫做:"CriteriaEntries"的ArrayList中, 并且提供了對應公有方法, 返回該list的Iterator迭代器.
經過上述分析, 筆者就有思路了:
利用公有方法獲取CriteriaEntries的迭代器, 通過遍歷刪除迭代器中每一個元素, 即實現了清空條件的目的.
直接簡單粗暴, 再次反射, 將dc名為"impl"屬性重置, 即new一個新的ArrayList賦給它.
代碼實現 思路一: 獲取迭代器, 遍歷刪除private void eraseCriteria(DetachedCriteria dc) { try { Field impl = dc.getClass().getDeclaredField("impl"); impl.setAccessible(true); // 得到實現類 CriteriaImpl cimpl = (CriteriaImpl) impl.get(dc); // 思路一: 遍歷criterionEntries, 清空所有 // 利用實現類的公有方法獲取迭代器 Iterator思路二: 直接重置CriteriaEntriescriterionEntryIterator = cimpl.iterateExpressionEntries(); while (criterionEntryIterator.hasNext()) { // 刪除本元素 criterionEntryIterator.remove(); } } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } Log.end(); }
private void eraseCriteria(DetachedCriteria dc) { try { Field impl = dc.getClass().getDeclaredField("impl"); impl.setAccessible(true); // 得到實現類 CriteriaImpl cimpl = (CriteriaImpl) impl.get(dc); // 思路二: 再次反射, 直接將criterionEntries置空. // 獲取criterionEntries屬性 Field criterionEntries = cimpl.getClass().getDeclaredField("criterionEntries"); criterionEntries.setAccessible(true); // 重置條件list criterionEntries.set(cimpl, new ArrayList()); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } Log.end(); }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70733.html
一:字典表 字典信息:在項目中可能會使用到,已經存在的一些信息。 例如,客戶的級別:普通用戶,vip用戶... 客戶的來源:網絡營銷,電話營銷... 客戶所屬行業:電子商務,房地產... 客戶的性別:男,女 在保存用戶的時候,這些信息都是已經存在的,不應該讓用戶讓用戶來任意填寫, 而是通過下拉列表來讓用戶選擇。 這些已經存在的信息稱之為字典信...
一:字典表 字典信息:在項目中可能會使用到,已經存在的一些信息。 例如,客戶的級別:普通用戶,vip用戶... 客戶的來源:網絡營銷,電話營銷... 客戶所屬行業:電子商務,房地產... 客戶的性別:男,女 在保存用戶的時候,這些信息都是已經存在的,不應該讓用戶讓用戶來任意填寫, 而是通過下拉列表來讓用戶選擇。 這些已經存在的信息稱之為字典信...
摘要:是的簡稱,運行環境,為的運行提供了所需的環境。分割字符串,返回分割后的字符串數組。當計算的值相同時,我們稱之為沖突,的做法是用鏈表和紅黑樹存儲相同的值的。迭代器取代了集合框架中的,迭代器允許調用者在迭代過程中移除元素。 Java基礎1.JDK和JRE有什么區別? JDK 是java development kit的簡稱,java開發工具包,提供java的開發環境和運行環境。JRE 是j...
摘要:此時,我們不能在層使用因為它是和綁定的。可以解決這個問題,即在層,程序員使用來構造查詢條件,然后將這個作為方法調用參數傳遞給業務層對象。而業務層對象獲得之后,可以在范圍內直接構造,進行查詢。參考問題十二投影聚合和分組是的實例工廠。 問題九、Hibernate里面如何用Criteria 查詢記錄數 【問題描述】在工作中,有一個比較復雜的feature使用的是hibernate的Crite...
閱讀 1261·2021-09-02 13:36
閱讀 2714·2019-08-30 15:44
閱讀 2972·2019-08-29 15:04
閱讀 3193·2019-08-26 13:40
閱讀 3643·2019-08-26 13:37
閱讀 1172·2019-08-26 12:22
閱讀 1003·2019-08-26 11:36
閱讀 1214·2019-08-26 10:41