最近項目用上了條件查詢,參考了Hibernate文檔,整理出一份筆記
創建條件查詢實例
1
Criteria criteria = session.createCriteria(User.class);
限制結果集
org.hibernate.criterion.Restrictions類 定義獲得某些內置Criterion類型的工廠方法
criteria.add(Restrictions.eq("username", "yanshi"));
//輸出yanshi 1
// yanshi 2
Restrictions.and()邏輯與
criteria.add(Restrictions.and(Restrictions.like("username", "y%"),Restrictions.ne("id", 1)));

/**//*
yanshi2
7
yanshi3
8
yanshi
9
*/
Restrictions.conjunction()也是邏輯與,但是和and區別一直不太清楚,GOOGLE了一下也沒找到明確的說法,最后看了下生成的SQL,個人理解應該是添加一個查詢集合,按文檔叫法就是邏輯分組
1
//criteria.add(Restrictions.like("username", "y%")).add(Restrictions.conjunction().add(Restrictions.ne("id", 1)));
2
3
Hibernate:
4
select
5
this_.id as id1_0_,
6
this_.role as role1_0_,
7
this_.username as username1_0_,
8
this_.password as password1_0_
9
from
10
test.user this_
11
where
12
this_.username like ?
13
and (
14
this_.id<>?
15
) limit ?
16
17
//criteria.add(Restrictions.like("username", "y%")).add(Restrictions.conjunction().add(Restrictions.ne("id", 1)));
18
19
Hibernate:
20
select
21
this_.id as id1_0_,
22
this_.role as role1_0_,
23
this_.username as username1_0_,
24
this_.password as password1_0_
25
from
26
test.user this_
27
where
28
(
29
this_.username like ?
30
and this_.id<>?
31
) limit ?
32
33
Restrictions.or()邏輯或
criteria.add(Restrictions.or(Restrictions.like("username", "y%"),Restrictions.eq("id",1)));

/**//*yanshi
1
yanshi2
2
yanshi3
2
yanshi*/
同樣Restrictions.disjunction()也是添加一個or查詢集合
1
//criteria.add(Restrictions.like("username", "y%")).add(Restrictions.disjunction().add(Restrictions.ne("id", 1)).add(Restrictions.in("username",new String[]{"yanshi","yanshi1"})).add(Restrictions.like("username", "yanshi")));
2
3
4
Hibernate:
5
select
6
this_.id as id1_0_,
7
this_.role as role1_0_,
8
this_.username as username1_0_,
9
this_.password as password1_0_
10
from
11
test.user this_
12
where
13
this_.username like ?
14
and (
15
this_.id<>?
16
or this_.username in (
17
?, ?
18
)
19
or this_.username like ?
20
) limit ?
Restrictions.in() 參數位于列表中的值
criteria.add(Restrictions.in("id",new Integer[]{1,2,3}));
/*
yanshi
1
stone1
2
stone
3
*/
Restrictions.between() value1~value2之間包括本身任意值
criteria.add(Restrictions.between("id", 1, 3));
/*
yanshi
1
stone1
2
stone
3
*/
Restrictions.not() 邏輯非,可以和其他條件組合
criteria.add(Restrictions.not(Restrictions.eq("id",1)));

criteria.add(Restrictions.not(Restrictions.between("id", 1, 3)));

criteria.add(Restrictions.not(Restrictions.in("id",new Integer[]{1,2,3})));
Restrictions最有意思的功能就是可以直接使用SQL
Restrictions.sqlRestriction()
criteria.add(Restrictions.like("username", "yan%")).add(Restrictions.sqlRestriction("{alias}.id=?",1,Hibernate.INTEGER));

//yanshi 1

如果有多個參數,可以傳入一個數組

Integer[] agrs=new Integer[]
{1,2};

Type[] types=new Type[]
{Hibernate.INTEGER,Hibernate.INTEGER};
criteria.add(Restrictions.like("username", "yan%")).add(Restrictions.sqlRestriction("{alias}.id=? or {alias}.id=?",agrs,types));


/**//*
yanshi
1
stone1
2
*/
其他
Restrictions.eq() Restrictions.ne() 等于,不等于
Restrictions.gt() Restrictions.ge() 大于,大于或等于
Restrictions.lt() Restrictions.le() 小于,小于或等于
Restrictions.isnull() Restrictions.isNotnull() 等于空,不等于空
Restrictions.like() 匹配字符串
同樣的屬性使用多次時候,寫Restrictions嫌麻煩,可以用Property
1
Property username=Property.forName("username");
2
criteria.add(username.like("yansh%"));
關聯
關聯有兩種方式
createCriteria()和crerateAlias()
區別是前一個創建實力,后一個不創建
createCriteria()
1
criteria.add(Restrictions.like("username", "yan%")).createCriteria("role").add(Restrictions.eq("type","管理員"));
crerateAlias()
criteria.add(Restrictions.like("username", "yan%")).createAlias("role","r").add(Restrictions.eq("r.type", "管理員"));
crerateAlias() 適用于這樣的情況,比如表A 關聯表B 和C 需要查詢出B.name 等于C.name 的表A的數據
1
criteria.createAlias("BTABLE", "b").createAlias("CTABLE", "c").add(Restrictions.eqProperty("b.name", "c.name"));
如果想獲得管理對象的數據使用ResultTransformer
1
List list=criteria.createAlias("role","r").add(Restrictions.like("username", "yans%"));
2
3
criteria.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
4
5
Iterator iter=list.iterator();
6
while(iter.hasNext())
{
7
Map map=(Map) iter.next();
8
User u=(User) map.get(Criteria.ROOT_ALIAS);
9
System.out.println(u.getUsername()+"aaaa");
10
Role r=(Role) map.get("r");
11
System.out.println(r.getType()+"bbbb");
12
}
13
14
/**//*
15
yanshiaaaa
16
管理員bbbb
17
yanshi2aaaa
18
普通用戶bbbb
19
yanshi3aaaa
20
普通用戶bbbb
21
yanshiaaaa
22
普通用戶bbbb
23
24
*/
關聯抓取
Criteria criteria = session.createCriteria(User.class).setFetchMode("role", FetchMode.SELECT);
如果多個關聯可以用
Criteria criteria = session.createCriteria(User.class).setFetchMode("role", FetchMode.JOIN).setFetchMode("role.xxx",FetchMode.JOIN);
FetchMode.JOIN 和 FetchMode.SELECT 前一個是采用連接解決N+1的問題,SELECT產生大量查詢語句........產生N+1 問題
查詢示例
1
User user = new User();
2
Role role = new Role();
3
//role.setId(1);
4
role.setType("管理員");
5
user.setRole(role);
6
criteria.add(Example.create(user));
7
8
//可以使用關聯,但是貌似用ID作為條件沒有效果
9
criteria.add(Example.create(user)).createCriteria("role").add(Example.create(user.getRole()));
enableLike()
對于字符串可以設置匹配模式
1
Example.create(user).enableLike(MatchMode.ANYWHERE)
MatchMode.ANYWHERE 任何位置
MacthMode.END 匹配結尾
MacthMode.START 匹配開頭
MatchMode.EXACT 精確匹配
其他的一些設置
excludeNone() 忽略NULL
excludeZeroes()忽略0
excludeProperty("屬性名") 忽略指定屬性
投影
Projections可以進行一些運算操作
Projections.avg(propertyName)統計指定屬性平均數
Projections.count(propertyName)統計指定屬性的行數
Projections.max(propertyName) 最大值
Projections.min(propertyName) 最小值
1
int totalCount = new Integer(criteria.setProjection(Projections.rowCount()).uniqueResult().toString());
2
criteria.setProjection(null);
3
criteria.setFirstResult(first);
4
criteria.setMaxResults(max);
5
criteria.setResultTransform(Criteria.ROOT_ENTITY);
注意 一定要在OrderBy和setFirstResult setMaxResults 之前使用不然返回空,最后還要設置返回類型,不然默認為Object
Projections.distinct()用來處理重復數據
1
public List<User> list(int first, int max)
{
2
Session session = new Configuration().configure().buildSessionFactory()
3
.openSession();
4
Criteria criteria = session.createCriteria(User.class).setFetchMode("role", FetchMode.JOIN);
5
//取得ID值
6
criteria.setProjection(Projections.distinct(Projections.projectionList().add(Projections.groupProperty("password")).add(Projections.id())));
7
List ids=new ArrayList<Integer>();
8
for (Iterator iter = criteria.list().iterator(); iter.hasNext();)
{
9
Object[] values = (Object[]) iter.next();
10
ids.add((Integer)values[1]);
11
}
12
//用in來查詢數據
13
criteria.add(Restrictions.in("id",ids));
14
int totalCount = new Integer(criteria.setProjection(
15
Projections.rowCount()).uniqueResult().toString());
16
criteria.setProjection(null);
17
criteria.setFirstResult(first);
18
criteria.setMaxResults(max);
19
criteria.setResultTransformer(Criteria.ROOT_ENTITY);
20
List<User> list = criteria.list();
21
return list;
22
}
需要說明的是
1
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
也是出來重復數據的,但是該方法是在結果集中處理,對分頁影響比較大,比如實際上查詢出10條數據,重復2條,重復處理后實際顯示9條數據,這樣和分頁的總數就不一致了
投影可以設置別名供其他投影使用
1
criteria.setProjection(Projections.groupProperty("username").as("name")).addOrder(Order.desc("name"))
同樣可以Property.forName來設置投影
在SESSION創建查詢使用DetachedCriteria
1
DetachedCriteria c=DetachedCriteria.forClass(User.class);
posted on 2009-12-21 23:13
巖石 閱讀(481)
評論(0) 編輯 收藏