zoukankan      html  css  js  c++  java
  • Hibernate 中Criteria Query查询详解【转】

    当查询数据时,人们往往需要设置查询条件。在SQL或HQL语句中,查询条件常常放在where子句中。此外,Hibernate还支持Criteria查询(Criteria Query),这种查询方式把查询条件封装为一个Criteria对象。在实际应用中,使用Session的createCriteria()方法构建一个org.hibernate.Criteria实例,然后把具体的查询条件通过Criteria的add()方法加入到Criteria实例中。这样,程序员可以不使用SQL甚至HQL的情况下进行数据查询,如例程9-1所示。

    例程9-1 Criteria应用实例

    Hibernate <wbr>中Criteria <wbr>Query查询详解【转】代码
    Criteria cr = session.createCriteria(Student.class); //生成一个Criteria对象
    cr.add(Restrictions.eq("name", "Bill"));//等价于where name=’Bill’
    List list = cr.list();
    Student stu = (Student)list.get(0);
    System.out.println(stu.getName());

    1.常用的查询限制方法

    在例程9-1中,Restrictions.eq()方法表示equal,即等于的情况。Restrictions类提供了查询限制机制。它提供了许多方法,以实现查询限制。这些方法及其他一些criteria常用查询限制方法列于表9-1中。

    表9-1 Criteria Query常用的查询限制方法

    方 法

    说 明

    Restrictions.eq()

    equal,=

    Restrictions.allEq()

    参数为Map对象,使用key/value进行多个等于的对比,相当于多个Restrictions.eq()的效果

    Restrictions.gt()

    greater-than, >

    Restrictions.lt()

    less-than, <

    Restrictions.le()

    less-equal, <=

    Restrictions.between()

    对应SQL的between子句

    Restrictions.like()

    对应SQL的like子句

    Restrictions.in()

    对应SQL的in子句

    Restrictions.and()

    and关系

    Restrictions.or()

    or关系

    Restrictions.isNull()

    判断属性是否为空,为空返回true,否则返回false

    Restrictions.isNotNull()

    与Restrictions.isNull()相反

    Order.asc()

    根据传入的字段进行升序排序

    Order.desc()

    根据传入的字段进行降序排序

    MatchMode.EXACT

    字符串精确匹配,相当于“like 'value'”

    MatchMode.ANYWHERE

    字符串在中间位置,相当于“like '%value%'”

    MatchMode.START

    字符串在最前面的位置,相当于“like 'value%'”

    MatchMode.END

    字符串在最后面的位置,相当于“like '%value'”

    例1:查询学生名字以t开头的所有Student对象。

    Criteria cr = session.createCriteria(Student.class);
    cr.add(Restrictions.like(“name”, “t%”))
    List list = cr.list();
    Student stu = (Student)list.get(0);
    或者使用另一种方式:
    Criteria cr = session.createCriteria(Student.class);
    cr.add(Restrictions.like(“name”, “t”, MatchMode.START))
    List list = cr.list();
    Student stu = (Student)list.get(0);
    例2:查询学生姓名在Bill, Jack和Tom之间的所有Student对象。
    String[] names = {“Bill”, “Jack”, “Tom”}
    Criteria cr = session.createCriteria(Student.class);
    cr.add(Restrictions.in(“name”, names))
    List list = cr.list();
    Student stu = (Student)list.get(0);
    例3:查询学生的年龄age等于22或age为空(null)的所有Student对象。
    Criteria cr = session.createCriteria(Student.class);
    cr.add(Restrictions.eq(“age”, new Integer(22));
    cr.add(Restrictions.isNull(“age”));
    List list = cr.list();
    Student stu = (Student)list.get(0);
    例4:查询学生姓名以字母F开头的所有Student对象,并按姓名升序排序。
    Criteria cr = session.createCriteria(Student.class);
    cr.add(Restrictions.like(“name”, “F%”);
    cr.addOrder(Order.asc(“name”));
    List list = cr.list();
    Student stu = (Student)list.get(0);

    调用Order.asc的方法应是Criteria的addOrder()方法。

    使用add()方法加入条件时,预设是使用and来组合条件,如果要用or的方式来组合条件,则可以使用Restrictions.or()方法,例如结合age等于(eq)20或(or)age为空(isNull)的条件:

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.add(Restrictions.or(
    3. Restrictions.eq("age"new Integer(20)),
    4. Restrictions.isNull("age")
    5. ));
    6. 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)

    使用Criteria进行查询时,不仅仅能组合出SQL中where子句的功能,还可以组合出如排序、统计、分组等的查询功能。这就是Criteria进阶查询。

    排序
    您可以使用Criteria进行查询,并使用org.hibernate.criterion.Order对结果进行排序,例如使用Oder.asc(),指定根据”age”由小到大排序(反之则使用desc()):

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.addOrder(Order.asc("age"));
    3. 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笔资料(如果有的话):

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.setFirstResult(51);
    3. criteria.setMaxResults(50);
    4. 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"作平均:

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.setProjection(Projections.avg("age"));
    3. 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:

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.setProjection(Projections.groupProperty("age"));
    3. 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,例如下面的程式会计算每个年龄各有多少个人:

    1. ProjectionList projectionList = Projections.projectionList();
    2. projectionList.add(Projections.groupProperty("age"));
    3. projectionList.add(Projections.rowCount());
    4. Criteria criteria = session.createCriteria(User.class);
    5. criteria.setProjection(projectionList);
    6. 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也不方便,如果有一个已知的物件,则可以根据这个物件作为查询的依据,看看是否有属性与之类似的物件,例如:

    1. User user = new User();
    2. user.setAge(new Integer(30));
    3. Criteria criteria = session.createCriteria(User.class);
    4. criteria.add(Example.create(user));
    5. List users = criteria.list();

    Criteria进阶查询中,您可以透过 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开头的资料:

    1. Criteria criteria = session.createCriteria(User.class);
    2. criteria.add(Restrictions.sqlRestriction(
    3. "{alias}.name LIKE (?)", "cater%", Hibernate.STRING));
    4. 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子句的查询,则可以如下:

    1. Criteria criteria = session.createCriteria(User.class);
    2. Integer[] ages = {new Integer(20), new Integer(40)};
    3. Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER};
    4. criteria.add(Restrictions.sqlRestriction(
    5. "{alias}.age BETWEEN (?) AND (?)", ages, types));
    6. 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 (?)

    2.连接限制

    在Criteria 查询中使用FetchMode来实现连接限制。在HQL语句中,可以通过fetch关键字来表示预先抓取(Eager fetching),如下所示:

    from Group g
    left join fetch g.students s
    where g.name like ' 05'
    可以使用Criteria的API完成同样的功能,如下所示:
    Criteria cr = session.createCriteria(Group.class);
    cr.setFetchMode(“students”, FetchMode.EAGER);
    cr.add(Restrictions.like(“name”, “2005”, MatchMode.END))
    List list = cr.list();
    以上两种方式编写的代码,都使用相同的SQL语句完成它们的功能,如下所示:
    select g.*, s.* from Group g
    left outer join Student s
    on g.id = s.group_id
    where g.name like ' 05'
    );
  • 相关阅读:
    Dynamics AX 2012 R2 配置E-Mail模板
    Dynamics AX 2012 R2 设置E-Mail
    Dynamics AX 2012 R2 为运行失败的批处理任务设置预警
    Dynamics AX 2012 R2 耗尽用户
    Dynamics AX 2012 R2 创建一个专用的批处理服务器
    Dynamics AX 2012 R2 创建一个带有负载均衡的服务器集群
    Dynamics AX 2012 R2 安装额外的AOS
    Dynamics AX 2012 R2 将系统用户账号连接到工作人员记录
    Dynamics AX 2012 R2 从代码中调用SSRS Report
    Dynamics AX 2012 R2 IIS WebSite Unauthorized 401
  • 原文地址:https://www.cnblogs.com/linjiaxin/p/6100129.html
Copyright © 2011-2022 走看看