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