寫在前面:session
最近在項目中使用了Criteria的分頁查詢,當查詢的數據沒有重複的記錄還好,可是當數據有關聯並出現重複記錄的時候,就要去重,那麼就會出現查詢的記錄數與實際的不一致的問題。這裏也記錄一下解決的辦法。測試
這裏只是拿學生Student表與班級來舉例,沒有通過測試this
1.查詢所有的數據,不進行分頁處理,使用distinct去重徹底是能夠的,代碼大體以下:spa
/** * 查詢全部的學生 不分頁去重 * @return * @throws Exception */ public List<Student> listAllStudent() throws Exception { Session session = this.getCurrentSession(); Criteria criteria = session.createCriteria(Student.class); //去重 不分頁 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); List<Student> list = criteria.list(); return list; }
2.查詢所有的數據,可是要分頁查詢。先來看下出問題的代碼,大體以下:code
/** * 查詢全部的學生 分頁去重 * 問題代碼 此種方式當有複雜的關聯關係時 查出來的數據記錄會與實際的不一致 * @return * @throws Exception */ public List<Student> listAllStudent2() throws Exception { Session session = this.getCurrentSession(); Criteria criteria = session.createCriteria(Student.class); //去重 會出現數據記錄數不一致問題 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); //分頁 List<Student> list = criteria.setFirstResult(0).setMaxResults(5).list(); return list; }
通常狀況下,咱們都會使用上面的代碼,可是通過數據的測試就會發現,分頁後查詢出來的代碼雖然去重了,可是數據的記錄條數會出問題,與實際的並不一致。之因此會出現這樣的問題,是由於,上面的代碼的執行順序是查詢出全部符合條件的記錄,而後是先分頁,分頁分好了,再去重,那若是查詢出來的第一頁數據有3條,裏面有兩個記錄是重複的,那麼通過去重後,第一頁顯示出來的數據就只有2條;而咱們正常分頁去重的順序應該是,先查詢出全部符合條件的記錄,而後去重,最後纔是在分頁。orm
下面就提供一種解決方案。大體的代碼以下:blog
/** * 查詢全部的學生 分頁去重 正確的打開方式 * @return * @throws Exception */ public List<Student> listAllStudent3() throws Exception { Session session = this.getCurrentSession(); Criteria criteria = session.createCriteria(Student.class); //1.分頁查詢出全部的Student的惟一標識studentId criteria.setProjection(Projections.distinct(Property.forName("studentId"))); List<String> studentIdList = criteria.setFirstResult(0).setMaxResults(5).list(); //2.從新構建criteria查詢 Criteria criteria2 = session.createCriteria(Student.class); List<Student> resultList = new ArrayList<Student>(); //3.查詢全部studentId在studentIdList裏的Student if(studentIdList.size()>0){ criteria2.add(Restrictions.in("studentId",studentIdList)); //這裏才使用去重 不須要再次分頁了 criteria2.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); resultList = criteria2.list(); } return resultList; }
上面代碼基本就完成了使用Criteria查詢,而且能夠分頁,能夠去重。大體步驟能夠分爲三個部分:get
舉例:表a,表b,兩個表有關聯關係,如今要查詢出全部符合條件的a記錄,而且使用分頁查詢it
1.分頁查詢出全部的a的惟一標識屬性集合list,注意這裏要進行分頁io
2.再次從新構建criteria查詢
3.查詢出全部a的惟一屬性包含在list集合中的a記錄,並去重
固然了,這只是個大體的步驟,具體的代碼還要根據本身的項目來看,對了,還要稍微注意下,當Criteria查詢使用別名的時候,記得選擇合適本身項目的鏈接方式,好比,當表a中有外鍵與表b關聯,當a的外鍵是null的時候,要想查詢此條記錄出來,要使用表a左外鏈接表b的方式來進行查詢