-
- Hibernate中Criteria的完整用法
- 最近在项目中使用 Spring 和 Hibernate 进行开发,有感于 Criteria 比较好用,在查询方法
-
- 设计上可以灵活的根据 Criteria 的特点来方便地进行查询条件的组装。现在对 Hibernate的Criteria 的用法进行总结:
- Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供了 Criteria和DetachedCriteria 。
- Criteria 和 DetachedCriteria 的主要区别在于创建的形式不一样, Criteria 是在线的,所
- 以它是由 Hibernate Session 进行创建的;而 DetachedCriteria 是离线的,创建时无需
- Session,DetachedCriteria 提供了 2 个静态方法 forClass(Class) 或 forEntityName(Name)
- 进行DetachedCriteria 实例的创建。 Spring 的框架提供了getHibernateTemplate
- ().findByCriteria(detachedCriteria) 方法可以很方便地根据DetachedCriteria 来返回查询结
- 果。
- Criteria 和 DetachedCriteria 均可使用 Criterion 和 Projection 设置查询条件。可以设
- 置 FetchMode( 联合查询抓取的模式 ) ,设置排序方式。对于 Criteria 还可以设置 FlushModel
- (冲刷 Session 的方式)和 LockMode (数据库锁模式)。
- 下面对 Criterion 和 Projection 进行详细说明。
- Criterion 是 Criteria 的查询条件。Criteria 提供了 add(Criterion criterion) 方法来
- 添加查询条件。
- Criterion 接口的主要实现包括: Example 、 Junction 和 SimpleExpression 。而
- Junction 的实际使用是它的两个子类 conjunction 和 disjunction ,分别是使用 AND 和 OR 操
- 作符进行来联结查询条件集合。
- Criterion 的实例可以通过 Restrictions 工具类来创建,Restrictions 提供了大量的静态
- 方法,如 eq (等于)、 ge (大于等于)、 between 等来方法的创建 Criterion 查询条件
- (SimpleExpression 实例)。除此之外, Restrictions 还提供了方法来创建 conjunction 和
- disjunction 实例,通过往该实例的 add(Criteria) 方法来增加查询条件形成一个查询条件集合
- 。
- 至于 Example 的创建有所不同, Example 本身提供了一个静态方法 create(Object
- entity) ,即根据一个对象(实际使用中一般是映射到数据库的对象)来创建。然后可以设置一些
- 过滤条件:
- Example exampleUser =Example.create(u)
- .ignoreCase() // 忽略大小写
- .enableLike(MatchMode.ANYWHERE);
- // 对 String 类型的属性,无论在那里值在那里都匹配。相当于 %value%
- Project 主要是让 Criteria 能够进行报表查询,并可以实现分组。 Project 主要有
- SimpleProjection 、 ProjectionList 和 Property 三个实现。其中 SimpleProjection 和
- ProjectionList 的实例化是由内建的 Projections 来完成,如提供的 avg 、 count 、 max 、
- min 、 sum 可以让开发者很容易对某个字段进行统计查询。
- Property 是对某个字段进行查询条件的设置,如通过Porperty.forName(“color”).in
- (new String[]{“black”,”red”,”write”}); 则可以创建一个 Project 实例。通过
- criteria 的 add(Project) 方法加入到查询条件中去。
- 使用 Criteria 进行查询,主要要清晰的是 Hibernate 提供了那些类和方法来满足开发中查
- 询条件的创建和组装,下面介绍几种用法:
- 1. 创建一个Criteria 实例
- org.hibernate.Criteria接口表示特定持久类的一个查询。Session是 Criteria实例的工厂。
- Criteria crit = sess.createCriteria(Cat.class);
- crit.setMaxResults(50);
- List cats = crit.list();
- 2. 限制结果集内容
- 一个单独的查询条件是org.hibernate.criterion.Criterion 接口的一个实例。
- org.hibernate.criterion.Restrictions类 定义了获得某些内置Criterion类型的工厂方法。
- List cats = sess.createCriteria(Cat.class)
- .add( Restrictions.like("name", "Fritz%") )
- .add( Restrictions.between("weight", minWeight, maxWeight) )
- .list();
- 约束可以按逻辑分组。
- List cats = sess.createCriteria(Cat.class)
- .add( Restrictions.like("name", "Fritz%") )
- .add( Restrictions.or(
- Restrictions.eq( "age", new Integer(0) ),
- Restrictions.isNull("age")
- ) )
- .list();
- List cats = sess.createCriteria(Cat.class)
- .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
- .add( Restrictions.disjunction()
- .add( Restrictions.isNull("age") )
- .add( Restrictions.eq("age", new Integer(0) ) )
- .add( Restrictions.eq("age", new Integer(1) ) )
- .add( Restrictions.eq("age", new Integer(2) ) )
- ) )
- .list();
- Hibernate提供了相当多的内置criterion类型(Restrictions 子类), 但是尤其有用的是可以允许
- 你直接使用SQL。
- List cats = sess.createCriteria(Cat.class)
- .add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%",
- Hibernate.STRING) )
- .list();
- {alias}占位符应当被替换为被查询实体的列别名。
- Property实例是获得一个条件的另外一种途径。你可以通过调用Property.forName() 创建一个
- Property。
- Property age = Property.forName("age");
- List cats = sess.createCriteria(Cat.class)
- .add( Restrictions.disjunction()
- .add( age.isNull() )
- .add( age.eq( new Integer(0) ) )
- .add( age.eq( new Integer(1) ) )
- .add( age.eq( new Integer(2) ) )
- ) )
- .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )
- .list();
- 3. 结果集排序
- 你可以使用org.hibernate.criterion.Order来为查询结果排序。
- List cats = sess.createCriteria(Cat.class)
- .add( Restrictions.like("name", "F%")
- .addOrder( Order.asc("name") )
- .addOrder( Order.desc("age") )
- .setMaxResults(50)
- .list();
- List cats = sess.createCriteria(Cat.class)
- .add( Property.forName("name").like("F%") )
- .addOrder( Property.forName("name").asc() )
- .addOrder( Property.forName("age").desc() )
- .setMaxResults(50)
- .list();
- 4. 关联
- 你可以使用createCriteria()非常容易的在互相关联的实体间建立 约束。
- List cats = sess.createCriteria(Cat.class)
- .add( Restrictions.like("name", "F%")
- .createCriteria("kittens")
- .add( Restrictions.like("name", "F%")
- .list();
- 注意第二个 createCriteria()返回一个新的 Criteria实例,该实例引用kittens 集合中的元素。
- 接下来,替换形态在某些情况下也是很有用的。
- List cats = sess.createCriteria(Cat.class)
- .createAlias("kittens", "kt")
- .createAlias("mate", "mt")
- .add( Restrictions.eqProperty("kt.name", "mt.name") )
- .list();
- (createAlias()并不创建一个新的 Criteria实例。)
- Cat实例所保存的之前两次查询所返回的kittens集合是 没有被条件预过滤的。如果你希望只获得
- 符合条件的kittens, 你必须使用returnMaps()。
- List cats = sess.createCriteria(Cat.class)
- .createCriteria("kittens", "kt")
- .add( Restrictions.eq("name", "F%") )
- .returnMaps()
- .list();
- Iterator iter = cats.iterator();
- while ( iter.hasNext() ) {
- Map map = (Map) iter.next();
- Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
- Cat kitten = (Cat) map.get("kt");
- }
- 5. 动态关联抓取
- 你可以使用setFetchMode()在运行时定义动态关联抓取的语义。
- List cats = sess.createCriteria(Cat.class)
- .add( Restrictions.like("name", "Fritz%") )
- .setFetchMode("mate", FetchMode.EAGER)
- .setFetchMode("kittens", FetchMode.EAGER)
- .list();
- 这个查询可以通过外连接抓取mate和kittens。
- 6. 查询示例
- org.hibernate.criterion.Example类允许你通过一个给定实例 构建一个条件查询。
- Cat cat = new Cat();
- cat.setSex('F');
- cat.setColor(Color.BLACK);
- List results = session.createCriteria(Cat.class)
- .add( Example.create(cat) )
- .list();
- 版本属性、标识符和关联被忽略。默认情况下值为null的属性将被排除。
- 可以自行调整Example使之更实用。
- Example example = Example.create(cat)
- .excludeZeroes() //exclude zero valued properties
- .excludeProperty("color") //exclude the property named "color"
- .ignoreCase() //perform case insensitive string comparisons
- .enableLike(); //use like for string comparisons
- List results = session.createCriteria(Cat.class)
- .add(example)
- .list();
- 甚至可以使用examples在关联对象上放置条件。
- List results = session.createCriteria(Cat.class)
- .add( Example.create(cat) )
- .createCriteria("mate")
- .add( Example.create( cat.getMate() ) )
- .list();
- 7. 投影(Projections)、聚合(aggregation)和分组(grouping)
- org.hibernate.criterion.Projections是 Projection 的实例工厂。我们通过调用
- setProjection()应用投影到一个查询。
- List results = session.createCriteria(Cat.class)
- .setProjection( Projections.rowCount() )
- .add( Restrictions.eq("color", Color.BLACK) )
- .list();
- List results = session.createCriteria(Cat.class)
- .setProjection( Projections.projectionList()
- .add( Projections.rowCount() )
- .add( Projections.avg("weight") )
- .add( Projections.max("weight") )
- .add( Projections.groupProperty("color") )
- )
- .list();
-
- 在一个条件查询中没有必要显式的使用 "group by" 。某些投影类型就是被定义为 分组投影,他
- 们也出现在SQL的group by子句中。
- 可以选择把一个别名指派给一个投影,这样可以使投影值被约束或排序所引用。下面是两种不同的
- 实现方式:
- List results = session.createCriteria(Cat.class)
- .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
- .addOrder( Order.asc("colr") )
- .list();
-
- List results = session.createCriteria(Cat.class)
- .setProjection( Projections.groupProperty("color").as("colr") )
- .addOrder( Order.asc("colr") )
- .list();
- alias()和as()方法简便的将一个投影实例包装到另外一个 别名的Projection实例中。简而言之,
- 当你添加一个投影到一个投影列表中时 你可以为它指定一个别名:
- List results = session.createCriteria(Cat.class)
- .setProjection( Projections.projectionList()
- .add( Projections.rowCount(), "catCountByColor" )
- .add( Projections.avg("weight"), "avgWeight" )
- .add( Projections.max("weight"), "maxWeight" )
- .add( Projections.groupProperty("color"), "color" )
- )
- .addOrder( Order.desc("catCountByColor") )
- .addOrder( Order.desc("avgWeight") )
- .list();
- List results = session.createCriteria(Domestic.class, "cat")
- .createAlias("kittens", "kit")
- .setProjection( Projections.projectionList()
- .add( Projections.property("cat.name"), "catName" )
- .add( Projections.property("kit.name"), "kitName" )
- )
- .addOrder( Order.asc("catName") )
- .addOrder( Order.asc("kitName") )
- .list();
- 也可以使用Property.forName()来表示投影:
- List results = session.createCriteria(Cat.class)
- .setProjection( Property.forName("name") )
- .add( Property.forName("color").eq(Color.BLACK) )
- .list();
- List results = session.createCriteria(Cat.class)
- .setProjection( Projections.projectionList()
- .add( Projections.rowCount().as("catCountByColor") )
- .add( Property.forName("weight").avg().as("avgWeight") )
- .add( Property.forName("weight").max().as("maxWeight") )
- .add( Property.forName("color").group().as("color" )
- )
- .addOrder( Order.desc("catCountByColor") )
- .addOrder( Order.desc("avgWeight") )
- .list();
- 8. 离线(detached)查询和子查询
- DetachedCriteria类使你在一个session范围之外创建一个查询,并且可以使用任意的 Session来
- 执行它。
- DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
- .add( Property.forName("sex").eq('F') );
- //创建一个Session
- Session session = .;
- Transaction txn = session.beginTransaction();
- List results = query.getExecutableCriteria(session).setMaxResults(100).list();
- txn.commit();
- session.close();
- DetachedCriteria也可以用以表示子查询。条件实例包含子查询可以通过 Subqueries或者
- Property获得。
- DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)
- .setProjection( Property.forName("weight").avg() );
- session.createCriteria(Cat.class)
- .add( Property.forName("weight).gt(avgWeight) )
- .list();
- DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
- .setProjection( Property.forName("weight") );
- session.createCriteria(Cat.class)
- .add( Subqueries.geAll("weight", weights) )
- .list();
- 相互关联的子查询也是有可能的:
- DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")
- .setProjection( Property.forName("weight").avg() )
- .add( Property.forName("cat2.sex").eqProperty("cat.sex") );
- session.createCriteria(Cat.class, "cat")
- .add( Property.forName("weight).gt(avgWeightForSex) )
- .list();
- 使用Hibernate時,即使您不了解SQL的使用與撰寫,也可以使用它所提供的API來進行SQL語句查詢,org.hibernate.Criteria對SQL進行封裝,您可以從Java物件的觀點來組合各種查詢條件,由Hibernate自動為您產生SQL語句,而不用特別管理SQL與資料庫相依的問題。
- 以最基本的查詢來說,如果您想要查詢某個物件所對應的資料表中所有的內容,您可以如下進行查詢:
- Criteria criteria = session.createCriteria(User.class);
- List users = criteria.list();
- for(Iterator it = users.iterator(); it.hasNext(); ) {
- User user = (User) it.next();
- System.out.println(user.getId() +
- " /t " + user.getName() +
- "/" + user.getAge());
- }
- Criteria建立後,若不給予任何的條件,預設是查詢物件所對應表格之所有資料,如果您執行以上的程式片段,並於設定檔中設定了了Hibernate的”show_sql”屬性,則可以在主控下看到以下的SQL語句之產生:
- Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_
- Criteria基本查詢條件設定
- org.hibernate.Criteria實際上是個條件附加的容器,如果想要設定查詢條件,則要使用org.hibernate.criterion.Restrictions的各種靜態方法傳回org.hibernate.criterion.Criteria實例,傳回的每個org.hibernate.criterion.Criteria實例代表著一個條件,您要使用org.hibernate.Criteria的add()方法加入這些條件實例,例如查詢”age”大於20且小於40的資料:
- Criteria criteria = session.createCriteria(User.class);
- criteria.add(Restrictions.gt("age", new Integer(20)));
- criteria.add(Restrictions.lt("age", new Integer(40)));
- List users = criteria.list();
- for(Iterator it = users.iterator(); it.hasNext(); ) {
- User user = (User) it.next();
- System.out.println(user.getId() +
- " /t " + user.getName() +
- "/" + user.getAge());
- }
- Restrictions的gt()方法表示大於(great than)的條件,而lt表示小於(less than)的條件,執行以上程式片段,觀察所產生的SQL語句,將使用where與and子句產來完成SQL的條件查詢:
- Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.age>? and this_.age
- 使用add()方法加入條件時,預設是使用and來組合條件,如果要用or的方式來組合條件,則可以使用Restrictions.or()方法,例如結合age等於(eq)20或(or)age為空(isNull)的條件:
- Criteria criteria = session.createCriteria(User.class);
- criteria.add(Restrictions.or(
- Restrictions.eq("age", new Integer(20)),
- Restrictions.isNull("age")
- ));
- List users = criteria.list();
- 觀察所產生的SQL語句,將使用where與or子句完成SQL的條件查詢:
- Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where (this_.age=? or this_.age is null)
- 您也可以使用Restrictions.like()方法來進行SQL中like子句的功能,例如查詢”name”中名稱為”just”開頭的資料:
- Criteria criteria = session.createCriteria(User.class);
- criteria.add(Restrictions.like("name", "just%"));
- List users = criteria.list();
- 觀察所產生的SQL語句如下:
- Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.name like ?
- 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關係
- Criteria進階查詢條件設定
- 使用Criteria進行查詢時,不僅僅能組合出SQL中where子句的功能,還可以組合出如排序、統計、分組等的查詢功能。
- 排序
- 您可以使用Criteria進行查詢,並使用org.hibernate.criterion.Order對結果進行排序,例如使用Oder.asc(),指定根據”age”由小到大排序(反之則使用desc()):
- Criteria criteria = session.createCriteria(User.class);
- criteria.addOrder(Order.asc("age"));
- List users = criteria.list();
- 注意在加入Order條件時,使用的是addOrder()方法,而不是add()方法,在產生SQL語句時,會使用order by與asc(desc)來進行排序指定:
- Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ order by this_.age asc
- 限定查詢筆數
- Criteria的setMaxResults()方法可以限定查詢回來的筆數,如果配合setFirstResult()設定傳回查詢結果第一筆資料的位置,就可以實現簡單的分頁,例如傳回第51筆之後的50筆資料(如果有的話):
- Criteria criteria = session.createCriteria(User.class);
- criteria.setFirstResult(51);
- criteria.setMaxResults(50);
- List users = criteria.list();
- 根據您所指定得資料庫,Hibernate將自動產生與資料庫相依的限定筆數查詢子句,例如在MySQL中,將使用limit產生以下的SQL語句:
- Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ limit ?, ?
- 統計動作
- 您可以對查詢結果進行統計動作,使用org.hibernate.criterion.Projections的avg()、rowCount()、count()、max()、min()、 countDistinct()等方法,再搭配Criteria的setProjection()方法加入條件設定,例如對查詢結果的"age"作平均:
- Criteria criteria = session.createCriteria(User.class);
- criteria.setProjection(Projections.avg("age"));
- List users = criteria.list();
- 上面的程式將由Hibernate自動產生SQL的avg函數進行平均計算:
- Hibernate: select avg(this_.age) as y0_ from T_USER this_
- 分組
- 還可以配合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();
- 上面的程式將由Hibernate自動產生SQL的group by子句進行分組計算:
- Hibernate: select this_.age as y0_ from T_USER this_ group by this_.age
- 如果想同時結合統計與分組功能,則可以使用org.hibernate.criterion.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();
- 觀察所產生的SQL語句,將使用group by先進行分組,再針對每個分組進行count函數的計數
- Hibernate: select this_.age as y0_, count(*) as y1_ from T_USER this_ group by this_.age
- 根據已知物件進行查詢
- 設定查詢條件並非一定要使用Restrictions,如果屬性條件很多,使用Restrictions也不方便,如果有一個已知的物件,則可以根據這個物件作為查詢的依據,看看是否有屬性與之類似的物件,例如:
- User user = new User();
- user.setAge(new Integer(30));
- Criteria criteria = session.createCriteria(User.class);
- criteria.add(Example.create(user));
- List users = criteria.list();
- 您可以透過org.hibernate.criterion.Example的create()方法來建立Example實例,Example實作了Criteria介面,因此可以使用add()方法加入至Criteria條件設定之中,Hibernate將自動過濾掉空屬性,根據已知物件上已設定的屬性,判定是否產生於where子句之中:
- Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where (this_.age=?)
- 設定SQL範本
- 如果您了解如何撰寫SQL語句,想要設定一些Hibernate產生SQL時的範本,您也可以使用Restrictions的sqlRestriction()方法,提供SQL語法範本作限定查詢,例如查詢name以cater開頭的資料:
- Criteria criteria = session.createCriteria(User.class);
- criteria.add(Restrictions.sqlRestriction("{alias}.name LIKE (?)", "cater%", Hibernate.STRING));
- List users = criteria.list();
- 其中alias將被替換為與User類別相關的名稱,而?將被替換為cater%,也就是第二個參數所提供的值,sqlRestriction()方法第一個參數所設定的是where子句的部份,所以在SQL撰寫時,不必再寫where,觀察所產生的SQL語句,將使用您所設定的SQL範本作為基礎,來完成SQL的條件查詢:
- Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.name LIKE (?)
- 如果有多個查詢條件,例如between子句的查詢,則可以如下:
- Criteria criteria = session.createCriteria(User.class);
- Integer[] ages = {new Integer(20), new Integer(40)};
- Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER};
- criteria.add(Restrictions.sqlRestriction("{alias}.age BETWEEN (?) AND (?)", ages, types));
- List users = criteria.list();
- 觀察所產生的SQL語句如下:
- Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.age BETWEEN (?) AND (?)
- 使用DetchedCriteria
- Criteria與Session綁定,其生命週期跟隨著Session結束而結束,使用Criteria時進行查詢時,每次都要於執行時期動態建立物件,並加入各種查詢條件,隨著Session的回收,Criteria也跟著回收。
- 為了能夠重複使用Criteria物件,在Hibernate 3中新增了org.hibernate.criterion.DetchedCriteria,您可以先建立DetchedCriteria實例,並加入各種查詢條件,並於需要查詢時再與Session綁定,獲得一個綁定Session的Criteria物件,例如:
- // 先建立DetchedCriteria物件
- DetachedCriteria detchedCriteria = DetachedCriteria.forClass(User.class);
- // 加入查詢條件
- detchedCriteria.add(Restrictions.ge("age",new Integer(25)));
- Session session = sessionFactory.openSession();
- // 綁定Session並返回一個Criteria實例
- Criteria criteria = detchedCriteria.getExecutableCriteria(session);
- List users = criteria.list();
- 結論
- Hibernate的Criteria API可以讓您使用物件的方式,組合出查詢資料庫系統的條件,Hibernate會自動依您所使用的資料庫,動態產生SQL語句,讓您的應用程式在存取資料庫時,不致於因撰寫了特定的SQL而相依於特定的資料庫,如果您的開發人員不熟悉SQL語句的撰寫,也可以試著使用Criteria來解決查詢資料庫的需求。
- 1、创建一个Criteria实例
- net.sf.hibernate.Criteria这个接口代表对一个特定的持久化类的查询。Session是用来制造Criteria实例的工厂。
- Criteria crit = sess.createCriteria(Cat.class);
- crit.setMaxResults(50);
- List cats = crit.list();
- 返回最多50条记录的结果集。
- 2、缩小结果集范围
- 一个查询条件(Criterion)是net.sf.hibernate.expression.Criterion接口的一个实例。类net.sf.hibernate.expression.Expression定义了获得一些内置的Criterion类型。
- List cats = sess.createCriteria(Cat.class)
- .add( Expression.like("name", "Fritz%") )
- .add( Expression.between("weight", minWeight, maxWeight) )
- .list();
- 表达式(Expressions)可以按照逻辑分组.
- List cats = sess.createCriteria(Cat.class)
- .add( Expression.like("name", "Fritz%") )
- .add( Expression.or(
- Expression.eq( "age", new Integer(0) ),
- Expression.isNull("age")
- ) )
- .list();
- 返回(name like "Fritz%" and age 等于0 或者 age 为空)的结果集
- List cats = sess.createCriteria(Cat.class)
- .add( Expression.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
- .add( Expression.disjunction()
- .add( Expression.isNull("age") )
- .add( Expression.eq("age", new Integer(0) ) )
- .add( Expression.eq("age", new Integer(1) ) )
- .add( Expression.eq("age", new Integer(2) ) )
- ) )
- .list();
- Expression.disjunction()----意思是可以按照逻辑分组
- 有很多预制的条件类型(Expression的子类)。有一个特别有用,可以让你直接嵌入SQL。
- List cats = sess.createCriteria(Cat.class)
- .add( Expression.sql("lower($alias.name) like lower(?)", "Fritz%", Hibernate.STRING) )
- .list();
- 其中的{alias}是一个占位符,它将会被所查询实体的行别名所替代。(原文:The {alias} placeholder with be replaced by the row alias of the queried entity.)
- 3、对结果排序
- 可以使用net.sf.hibernate.expression.Order对结果集排序.
- List cats = sess.createCriteria(Cat.class)
- .add( Expression.like("name", "F%")
- .addOrder( Order.asc("name") )
- .addOrder( Order.desc("age") )
- .setMaxResults(50)
- .list();
- 4、关联(Associations)
- 你可以在关联之间使用createCriteria(),很容易地在存在关系的实体之间指定约束。
- List cats = sess.createCriteria(Cat.class)
- .add( Expression.like("name", "F%")
- .createCriteria("kittens")
- .add( Expression.like("name", "F%")
- .list();
- 注意,第二个createCriteria()返回一个Criteria的新实例,指向kittens集合类的元素。
- 下面的替代形式在特定情况下有用。
- List cats = sess.createCriteria(Cat.class)
- .createAlias("kittens", "kt")
- .createAlias("mate", "mt")
- .add( Expression.eqProperty("kt.name", "mt.name") )
- .list();
- (createAlias())并不会创建一个Criteria的新实例。)
- 请注意,前面两个查询中Cat实例所持有的kittens集合类并没有通过criteria预先过滤!如果你希望只返回满足条件的kittens,你必须使用returnMaps()。
- List cats = sess.createCriteria(Cat.class)
- .createCriteria("kittens", "kt")
- .add( Expression.eq("name", "F%") )
- .returnMaps()
- .list();
- Iterator iter = cats.iterator();
- while ( iter.hasNext() ) {
- Map map = (Map) iter.next();
- Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
- Cat kitten = (Cat) map.get("kt");
- }
- 5、动态关联对象获取(Dynamic association fetching)
- 可以在运行时通过setFetchMode()来改变关联对象自动获取的策略。
- List cats = sess.createCriteria(Cat.class)
- .add( Expression.like("name", "Fritz%") )
- .setFetchMode("mate", FetchMode.EAGER)
- .list();
- 这个查询会通过外连接(outer join)同时获得 mate和kittens。
- 6、根据示例查询(Example queries)
- net.sf.hibernate.expression.Example类允许你从指定的实例创造查询条件。
- Cat cat = new Cat();
- cat.setSex('F');
- cat.setColor(Color.BLACK);
- List results = session.createCriteria(Cat.class)
- .add( Example.create(cat) )
- .list();
- 版本属性,表示符属性和关联都会被忽略。默认情况下,null值的属性也被排除在外。
- You can adjust how the Example is applied. 你可以调整示例(Example)如何应用。
- Example example = Example.create(cat)
- .excludeZeroes() //exclude zero valued properties
- .excludeProperty("color") //exclude the property named "color"
- .ignoreCase() //perform case insensitive string comparisons
- .enableLike(); //use like for string comparisons
- List results = session.createCriteria(Cat.class)
- .add(example)
- .list();
- 你甚至可以用示例对关联对象建立criteria。
- List results = session.createCriteria(Cat.class)
- .add( Example.create(cat) )
- .createCriteria("mate")
- .add( Example.create( cat.getMate() ) )
- .list();