Hibernate Gossip: Criteria 進階查詢
您可以使用Criteria進行查詢,並使用Order對結果進行排序,例如使用Oder.asc()由小到大排序(反之則使用desc()):
Criteria criteria = session.createCriteria(User.class);
criteria.addOrder(Order.asc("age"));
List users = criteria.list();
criteria.addOrder(Order.asc("age"));
List users = criteria.list();
setMaxResults()方法可以限定查詢回來的筆數,如果配合setFirstResult()設定傳回查詢結果第一筆資料的位置,就可以實現簡 單的分頁,例如傳回第51筆之後的50筆資料(如果有的話):
Criteria criteria = session.createCriteria(User.class);
criteria.setFirstResult(51);
criteria.setMaxResult(50);
List users = criteria.list();
criteria.setFirstResult(51);
criteria.setMaxResult(50);
List users = criteria.list();
您可以對查詢結果進行統計動作,使用Projections的avg()、rowCount()、count()、max()、min()、 countDistinct()等方法,例如對查詢結果的"age"作平均:
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(Projections.avg("age"));
List users = criteria.list();
Iterator iterator = users.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
criteria.setProjection(Projections.avg("age"));
List users = criteria.list();
Iterator iterator = users.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
還可以配合Projections的groupProperty()來對結果進行分組,例如以"age"進行分組,也就是如果資料中"age"如果有 20、20、25、30,則以下會顯示20、25、30:
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(Projections.groupProperty("age"));
List users = criteria.list();
Iterator iterator = users.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
criteria.setProjection(Projections.groupProperty("age"));
List users = criteria.list();
Iterator iterator = users.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
如果想結合統計與分組功能,則可以使用ProjectionList,例如下面的程式會計算每個年齡各有多少個人:
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.groupProperty("age"));
projectionList.add(Projections.rowCount());
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(projectionList);
List users = criteria.list();
Iterator iterator = users.iterator();
while(iterator.hasNext()) {
Object[] o = (Object[]) iterator.next();
System.out.println(o[0] + "/t" + o[1]);
}
projectionList.add(Projections.groupProperty("age"));
projectionList.add(Projections.rowCount());
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(projectionList);
List users = criteria.list();
Iterator iterator = users.iterator();
while(iterator.hasNext()) {
Object[] o = (Object[]) iterator.next();
System.out.println(o[0] + "/t" + o[1]);
}
如果有一個已知的物件,則可以根據這個物件作為查詢的依據,看看是否有屬性與之類似的物件,例如:
User user = new User();
user.setAge(new Integer(30));
Criteria criteria = session.createCriteria(User.class);
criteria.add(Example.create(user));
List users = criteria.list();
Iterator iterator = users.iterator();
System.out.println("id /t name/age");
while(iterator.hasNext()) {
User ur = (User) iterator.next();
System.out.println(ur.getId() +
" /t " + ur.getName() +
"/" + ur.getAge());
}
user.setAge(new Integer(30));
Criteria criteria = session.createCriteria(User.class);
criteria.add(Example.create(user));
List users = criteria.list();
Iterator iterator = users.iterator();
System.out.println("id /t name/age");
while(iterator.hasNext()) {
User ur = (User) iterator.next();
System.out.println(ur.getId() +
" /t " + ur.getName() +
"/" + ur.getAge());
}
在這個例子中,user物件中有已知的屬性"age"為30,使用Example會自動過濾掉user的空屬性,並以之作為查詢的依據,也就是找出 "age"同為30的資料。
Criteria可以進行複合查詢,即在原有的查詢基礎上再進行查詢,例如在Room對User的一對多關聯中,在查詢出所有的Room資料之後,希望再 查詢users中"age"為30的user資料:
Criteria roomCriteria = session.createCriteria(Room.class);
Criteria userCriteria = roomCriteria.createCriteria("users");
userCriteria.add(Restrictions.eq("age", new Integer(30)));
List rooms = roomCriteria.list(); // 只列出users屬性中有user之"age"為30的Room
Iterator iterator = rooms.iterator();