Hibernate中使用Criteria进行查询操作

Hibernate中可以使用Criteria的特点灵活的组装查询条件

其中,主要有Criteria和DetachedCriteria。两者的区别是一个是离线的,一个是在线。Criteria属于在线,需要由hibernateSession进行创建,而DetachedCriteria,无需hibernateSeession就可以进行创建。所以说我们可以在业务层中根据需求组装一个DetachedCriteria,然后在交给Dao进行查询。

下面主要讲的是DetachedCriteria

一、创建一个DetachedCriteria实例

DetachedCriteria提供了两种的静态方法forClass(Class)和forEntityName(Name)进行DetachedCriteria实例的创建

    DetachedCriteria criteria = DetachedCriteria.forClass(UC.class);

    DetachedCriteria criteria2 = DetachedCriteria.forEntityName("UC");

二、限制结果集内容

 使用DetachedCriteria中的add方法。传入的参数需要实现Criterion接口的一个实例。

我们可以使用org.hibernate.criterion.Restriciton类。它定义了获得某些内置的Criterion类型工厂方法

举个例子:

    DetachedCriteria criteria = DetachedCriteria.forClass(UC.class);

   criteria.add(Restrictions.like("user_realname", user_realName));

 Restrictions包含了基本的Sql的查询条件,例如like between eq(相等)le(小于) get(大于) ne(不相等) and(并且)等等。

需要注意的是在添加条件的时候,默认情况下是and


例如 以下表示的查询条件为user_realname字段的值要like user_realName(传入的参数值) 并且 user_code字段的值要like user_code(传入的参数值) 

    criteria.add(Restrictions.like("user_realname", user_realName))

    .add(Restrictions.like("user_code", user_code));


如果是习惯sql语句,可以使用 Restrictions.sql(sql); 传入sql语句作为查询条件

例如

    criteria.add(Restriction.sql("user_code like ? ","2222",Hibernate.STRING);


    对于Or和And查询条件,可以通过添加disjunction和conjunciton。这两个添加查询条件方式与DetachedCriteria类似,只不过所有添加的查询限制,全部是以Or和And的方式拼接的。最后,对DetachedCriteria的对象使用add方法,添加刚写的disjunction或conjunciton对象。举例来说

DetachedCriteria criteria = DetachedCriteria.forClass(UC.class);
criteria.add(Restrictions.eq("class_id", class_id));
Disjunction disJunction = Restrictions.disjunction();
disJunction.add(Restrictions.like("user_realname", user_realName));

disJunction.add(Restrictions.ilike("user_code", user_code));
criteria.add(disJunction);

最后的查询条件就是 classid = ? and user_realname = ? or user_code =?


三、多表连接查询

    使用DetachedCriteria类

DetachedCriteria org. hibernate. criterion. DetachedCriteria.createAlias( String associationPath, String alias)
方法实现。
其中 第一个参数表示是连接路径,也就是那个字段是作为连接点。第二个参数为别名。

    假设,现在有一个表 UC 三个自带安 uc_id(编号), uc_class (班级),uc_user(用户)。后两个为外键,uc_class对应class表的class_id。uc_user对应user表的user_id。另外两个表都只有一个字段。也就是刚提到的class_id和user_id。

    现在需要将三个表连接起来,uc表中一个记录,查询条件为class_id 为特定的一个值 并且user_id也为特定的一个值。则可以使用createAlias进行,并且之后设置连接表的查询条件使用的是alias.字段名的方式。

     DetachedCriteria criteria = DetachedCriteria.forClass(UC.class);
criteria.createAlias("uc_class", "uClass");
criteria.createAlias("uc_user", "uUser");
criteria.add(Restrictions.eq("uClass.class_id", "213"));

criteria.add(Restrictions.eq("uUser.user_id", "3123"));

    如果还有一个表需要进行连接,也是按照同样的道理。比如,class表中还有一个字段class_course对应course表中course_id。则查询uc表中一个记录,查询条件为course的名字为一个特定的值,可以如下。

     DetachedCriteria criteria = DetachedCriteria.forClass(UC.class);

criteria.createAlias("uc_class", "uClass");

criteria.createAlias("uc_class.class_course", "cCourse");

criteria.add(Restrictions.eq("cCourse.course_id", "3123"));


四、结果集排序

        使用org.hibernate.criterion.Order进行查询结果的排序。使用DetachedCritera的addOrder方法,传入的参数如下形式addOrder(Order.asc("字段名"))、addOrder(Order.desc("字段名"))

五、投影(Projections)、聚合(aggregation)和分组(grouping)

org.hibernate.criterion.Projections是Projection的实例工厂.我们通过调用setProjection()应用投影到一个查询。

        //设置投影,列数

        DetachedCriteria criteria = DetachedCriteria.forClass(UC.class);

criteria .setProjection(Projections.rowCount())

       //设置多个投影

  DetachedCriteria criteria = DetachedCriteria.forClass(UC.class);

 criteria.setProjection(Projections.projectionList()

              .add(Projections.rowCount())
              .add(Projections.max("字段名"))

 )

分组,两种方式,
第一种
使用setProjection()来设置分组的字段。
使用Projections.alias()来设置分组的别名,方便其他地方进行已用。
使用Projection.groupProperty来设置分组()
Projections.groupProperty
DetachedCriteria criteria = DetachedCriteria.forClass(UC.class);
criteria.setProjection(Projections.alias(Projections.groupProperty("字段名"),"别名"))
.addOrder(Order.asc("别名"));


第二种
使用setProjection()来设置分组的字段。
使用Projection.groupProperty来设置分组()
使用as来设置别名
DetachedCriteria criteria = DetachedCriteria.forClass(UC.class);
criteria.setProjection(Projections.groupProperty("字段名").as("别名"))
.addOrder(Order.asc("别名"));


也可以使用Property.forName()来表示投影:
DetachedCriteria criteria = DetachedCriteria.forClass(UC.class);
criteria.setProjection(Projections.projectionList()
              .add(Projections.rowCount().as("别名"))
              .add(Property.forName("字段名").max().as("别名"))
              .add(Property.forName("字段名").group().as("别名")
)
.addOrder(Order.desc("字段名"))

六、子查询

        DetachedCriteria也可以用以表示子查询.条件实例包含子查询可以通过Subqueries或者Property获得.
DetachedCriteria criteria = DetachedCriteria.forClass(UC.class)
.setProjection(Property.forName("uc_id").max());;
DetachedCriteria criteria2 = DetachedCriteria.forClass(Class.class)
criteria2.add(Property.forName(class_id).gt(criteria))

DetachedCriteria criteria = DetachedCriteria.forClass(UC.class)
.setProjection(Property.forName("uc_id"));;
DetachedCriteria criteria2 = DetachedCriteria.forClass(Class.class)
criteria2.add(Subqueries.geAll("uc_id",criteria))


相互关联的子查询也是有可能的:
DetachedCriteria criteria = DetachedCriteria.forClass(Class.class,"class")
.setProjection(Property.forName("num").avg())
.add(Property.forName("class.class_name").eqProperty("classTwo.class_name"));
DetachedCriteria criteria2 = DetachedCriteria.forClass(Class.class,"classTwo")
.add(Property.forName("num).gt(criteria));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值