以前寫hibernate查詢的時候都是萬年不變的HQL語句查詢,實在不行的就返璞歸真進行SQL查詢,這兩天寫代碼的時候見到了criteria的查詢方式,覺得挺好使,就在網上查查資料,項目里面的功能是完成了,但是對這個criteria的使用還是不是很熟練,建個小工程搭個hibernate,一邊看資料一邊做測試順便寫個博客記錄一下,一舉三得有木有。
Hibernate 定義了Criteriaspecification接口規范用來完成面向對象的條件查詢,Criteria 就是CriteriaSpecification的子接口。使用criteria時,你不需要去關心SQL語句,我想這對于SQL語句不太好的人來說是個最大的好處,好了廢話不多說,下面進入主題。
1、創建CriteriaCriteria的實現是離不開session的,也就是說Criteria的生命周期隨著session的生命周期的結束而結束,在使用Criteria進行查詢的時候,每次都要在執行時期動態建立物件,并且加入各種查詢條件,如果session回收了,那么Criteria也跟著回收。
Criteria的創建如下:
Criteria criteria = session.createCriteria(User1.class);
User1.class表示你要查詢的那個實體類。
2、Criteria查詢2.1@Test public void test() { Criteria criteria = session.createCriteria(User1.class); List<User1> list = criteria.list(); for(User1 u: list){ System.out.PRintln(u.toString()); } }
上述的方式就是Criteria的查詢方式,創建好Criteria之后,只要使用Criteria.list()方法即可查詢到你要查詢的實體的數據集合,可以看一下hibernate發出的sql語句:
Hibernate: select this_.uid as uid0_0_, this_.username as username0_0_, this_.pwd as pwd0_0_, this_.create_date as create4_0_0_ from test.t_user1 this_
這個跟我們寫HQL語句查詢時hibernate發出的sql語句是一樣。
2.2但是上面的查詢是對查詢出了全部的數據,有時候這并不是我們想要的,比如說我現在想查出姓張的用戶?這時候就需要使用Criteria方式添加條件了,先看一個代碼演示:
@Test public void test() { Criteria criteria = session.createCriteria(User1.class); criteria.add(Restrictions.like("name", "%張%")); List<User1> list = criteria.list(); for(User1 u: list){ System.out.println(u.toString()); } }
此時的查詢結果就是名字中帶有張字的用戶,上面說的姓張的用戶并不準確,這就是一個模糊查詢,like像的意思,也就是說在告訴criteria在查詢的時候給我找出來名字帶張字的,看我不揍死他們,就這意思。
此時控制臺發出的sql語句如下:
Hibernate: select this_.uid as uid0_0_, this_.username as username0_0_, this_.pwd as pwd0_0_, this_.create_date as create4_0_0_ from test.t_user1 this_ where this_.username like ?
要注意的地方有幾個:第一,like后面的兩個參數,第一個參數是實體類中對應的要查詢的字段,第二個參數是查詢的條件。
第二,模糊查詢可以用like,但是等于查詢就是eq、大于等于是ge、between表示兩者之間等等,這個在使用的時候需要注意一下,不同的查詢使用不同的可以叫做方法吧。
第三,添加條件的時候都是使用的criteria.add(),這個方法是沒有什么變化的。
第四,Restrictions是一個工具類,提供了大量的靜態方法,比如上面的like(),eq()等。
2.3上面的查詢條件是只有一個,那如果現在我有多個查詢條件怎么辦呢?這個也好辦,使用多個criteria.add()方法來滿足多條件的查詢,并且這多個條件之間屬于and的關系,如下所示:
@Test public void test() { Criteria criteria = session.createCriteria(User1.class); criteria.add(Restrictions.like("name", "%張%")); criteria.add(Restrictions.eq("passWord", "123")); List<User1> list = criteria.list(); for(User1 u: list){ System.out.println(u.toString()); } }
上面的查詢什么意思呢?意思就是在查找名字中帶有張字的同時還要滿足密碼是123的,兩個條件之間屬于并列關系,可以看一下hibernate發出的查詢語句:
Hibernate: select this_.uid as uid0_0_, this_.username as username0_0_, this_.pwd as pwd0_0_, this_.create_date as create4_0_0_ from test.t_user1 this_ where this_.username like ? and this_.pwd=?2.4
現在需求又變了,怎么變了呢?我現在不查名字里面帶張字的了,我現在知道倆密碼,一個123,一個234,就查密碼是123或者234的用戶,這時候怎么查啊?倆條件我寫倆criteria.add()方法嗎?但是這倆是屬于and關系啊,怎么搞?看下面的代碼:
@Test public void test() { Criteria criteria = session.createCriteria(User1.class); //criteria.add(Restrictions.like("name", "%張%")); //criteria.add(Restrictions.eq("password", "123")); criteria.add(Restrictions.or( Restrictions.eq("password", "123"), Restrictions.eq("password", "234"))); List<User1> list = criteria.list(); for(User1 u: list){ System.out.println(u.toString()); } }
再看一下hibernate發出的sql語句:
Hibernate: select this_.uid as uid0_0_, this_.username as username0_0_, this_.pwd as pwd0_0_, this_.create_date as create4_0_0_ from test.t_user1 this_ where (this_.pwd=? or this_.pwd=?)
可以看到sql語句最后是pwd=? or pwd = ?,進行的是或查詢,怎么實現的呢?就是Restrictions.or()方法,表示或的意思,里面的兩個參數又是兩個表達式,between操作與or操作差不多,大家試一下就會了,我就不再廢話了。
2.5列一下常用的常用的幾個Restrictions方法:
Restrictions.eq 等于 Restrictions.allEq 使用Map,使用key/value進行多個等于的比對 Restrictions.gt 大于 > Restrictions.ge 大于等于 >= Restrictions.lt 小于 < Restrictions.le 小于等于 <= Restrictions.between 對應SQL的BETWEEN子句 Restrictions.like 對應SQL的LIKE子句 Restrictions.in 對應SQL的in子句 Restrictions.and and關系 Restrictions.or or關系
3.criteria 排序、統計、分組等功能3.1 排序在使用criteria查詢結果集的時候是可以對所查詢的數據進行排序的,怎么做呢?看下面:
@Test public void test() { Criteria criteria = session.createCriteria(User1.class); criteria.addOrder(Order.asc("name")); List<User1> list = criteria.list(); for(User1 u: list){ System.out.println(u.toString()); } }
hibernate發出的sql語句:
Hibernate: select this_.uid as uid0_0_, this_.username as username0_0_, this_.pwd as pwd0_0_, this_.create_date as create4_0_0_ from test.t_user1 this_ order by this_.username asc
可以看到是根據用戶名進行正序排序,如果是倒序排列呢,只需要把asc換成desc就可以了,就是這么任性,但是要注意,此時添加的排序條件是使用的是criteria.addOrder()方法,而不是criteria.add().
3.2 偽分頁為什么叫偽分頁呢,我這里就是做一個簡單的演示操作,跟分頁扯不上什么關系,只不過查詢方法類似于分頁的查詢方法而已,所以我起名叫偽分頁,不過這個應該有具體的名字吧,不過我也不知道到底叫什么,就隨便叫吧,大家看了代碼就知道我說的是什么了。
@Test public void test() { Criteria criteria = session.createCriteria(User1.class); //criteria.addOrder(Order.asc("name")); criteria.setFirstResult(1); criteria.setMaxResults(3); List<User1> list = criteria.list(); for(User1 u: list){ System.out.println(u.toString()); } }
上sql語句:
Hibernate: select this_.uid as uid0_0_, this_.username as username0_0_, this_.pwd as pwd0_0_, this_.create_date as create4_0_0_ from test.t_user1 this_ limit ?, ?
看了上面的代碼大家有沒有覺得跟寫分頁時候的從第幾條記錄開始,每次顯示多少條記錄很像。
今天有事,先總結到這,下次再繼續總結。
新聞熱點
疑難解答