天天看點

它山之石(1)QBC

引用自他處,表示感謝!

現在假設有一個Student類,内有id,name,age屬性

String hql = "from Student s";

按照以前的做法,我們通常是

Query query = session.createQuery(hql);

或者要按照條件檢索的話.

String hql = "from Student s where s.name like '王%'"

Query query = session.createQuery(hql);

不用HQL而使用QBC的話,那麼代碼為:

Criteria criteria =session.createCriteria(Student.class);

Criterion criterion = Expression.like("name","王%");

這樣還看不出來.那我們把檢索條件加上年齡為22.

HQL:

String hql = "from Student s where s.name like '王%' and s.age= 22 ";

Query query = session.createQuery(hql);

List list = query.list();

QBC:

Criteria criteria =session.createCriteria(Student.class);

Criterion criterion1 = Expression.like("name","王%");

Criterion criterion2 = Expression.eq("age",newInteger(22));

criteria.add(criterion1).add(criterion2);

List list = criteria.list();

看上去煩瑣很多.但是做過項目的人都知道,當一個子產品業務邏輯發生改變的時候,往往要重寫sql,最煩也是最讨厭的就是拿着别人的hql或者sql,兩眼瞪的溜園找到底要修改什麼地方呢?

如果使用QBC大大的增加了代碼的可讀性,以及可維護性.

需要注意的是null值

比如我們要查找姓名為null的Student對象時應該這麼寫

Criteria criteria =session.createCriteria(Student.class);

Criterion criterion = Expression.isNull("name");

criteria.add(criterion).list();

以及使用between...and的時候

Criteria criteria =session.createCriteria(Student.class);

Criterion criterion1 = Expression.ge("age",new Integer(20));//下限

Criterion criterion2 = Expression.le("age",new Integer(25));//上限

//這裡也可以把上述兩個條件添加到第三個條件裡

Criterion criterion3 =Expression.and(criterion1,criterion2);

criteria.add(criterion3).list();

相當于from Student s where s.age between 20 and 25

等同于from Student s where s.age >= 20 and s.age <=25

下面是就HQL和QBC常用的查詢條件做的比較

表達式含義                   HQL                   QBC

大于等于                     >=                    Expression.ge()

大于                         >                     Expression.gt()

小于等于                     <=                    Expression.le()

小于                         <                     Expression.lt()

等于                         =                     Expression.eq()

不等于                       <>或者!=              Expression.ne()

為空                         is null               Expression.isNull()

不為空                       is notnull            Expression.isNotNull()

在指定範圍内                 betweenand            Expression.between()

不在指定範圍                 not betweenand        Expression.not(Expression.between())

屬于某個集合                 in                    Expression.in()

不屬于某個集合               notin                 Expression.not(Expression.in())

與                          and                   Expression.and()

或                          or                    Expression.or()

非                          not                   Expression.not()

模糊查詢                    like                  Expression.like

1、建立一個Criteria執行個體 net.sf.hibernate.Criteria這個接口代表對一個特定的持久化類的查詢。Session是用來制造Criteria執行個體的工廠。

Criteria crit = sess.createCriteria(Cat.class);

crit.setMaxResults(50);

List cats = crit.list();

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();

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的子類)。有一個特别有用,可以讓你直接嵌入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();

QBC