zoukankan      html  css  js  c++  java
  • Hibernate(十三):HQL查询(二)

    背景

    基于上一章节《Hibernate(十二):HQL查询(一)》,已经学习了一部分关于HQL的用法:

    1. HQL带参数查询
    2. HQL Order By排序查询
    3. HQL 设置实体参数查询

    本章节将会学习:HQL分页查询、HQL命名语句查询、HQL投影查询、HQL报表查询。

    HQL分页查询

     1)setFirstResult(int firstResult):设定从哪一个对象开始检索,参数firstResult表示这个对象在查询结果中的索引位置,索引位置的起始值为0。默认情况下,Query从查询结果中的第一个对象开始检索。

    2)setMaxResults(int maxResults):设定一次最多检索出的对象的数目。默认情况下,Query和Criteria接口检索出查询结果中所有的对象。

     1     @Test
     2     public void testHQLPageQuery() {
     3         String hql = "From Employee";
     4 
     5         int pageNum = 1;
     6         int pageSize = 10;
     7         Query query = session.createQuery(hql).setFirstResult((pageNum - 1) * pageSize).setMaxResults(pageSize);
     8 
     9         List<Employee> employees = query.list();
    10         System.out.println(employees.size());
    11         System.out.println(employees);
    12     }

    执行sql及结果:

     1 Hibernate: 
     2     select
     3         employee0_.ID as ID1_1_,
     4         employee0_.NAME as NAME2_1_,
     5         employee0_.SALARY as SALARY3_1_,
     6         employee0_.EMAIL as EMAIL4_1_,
     7         employee0_.DEPARTMENT_ID as DEPARTME5_1_ 
     8     from
     9         DX_EMPLOYEE employee0_ limit ?
    10 10
    11 [Employee [id=1, name=tommy0, salary=0.0, email=tommy0@dx.com]
    12 , Employee [id=2, name=tommy1, salary=1000.0, email=tommy1@dx.com]
    13 , Employee [id=3, name=tommy2, salary=2000.0, email=tommy2@dx.com]
    14 , Employee [id=4, name=tommy3, salary=3000.0, email=tommy3@dx.com]
    15 , Employee [id=5, name=tommy4, salary=4000.0, email=tommy4@dx.com]
    16 , Employee [id=6, name=tommy5, salary=5000.0, email=tommy5@dx.com]
    17 , Employee [id=7, name=tommy6, salary=6000.0, email=tommy6@dx.com]
    18 , Employee [id=8, name=tommy7, salary=7000.0, email=tommy7@dx.com]
    19 , Employee [id=9, name=tommy8, salary=8000.0, email=tommy8@dx.com]
    20 , Employee [id=10, name=tommy9, salary=9000.0, email=tommy9@dx.com]
    21 ]

    HQL命名语句查询

    在映射文件中定义命名查询语句:

    1)Hibernate允许在映射文件中定义字符串形式的查询语句;

    2)<query>元素用于定义一个HQL查询语句,它和<class>元素并列;

    1 <query name="findNewsByContent">
    2     <![CDATA[From News n Where n.content like :keyword]]>
    3 </query>

    3)在程序中,通过Session的getNamedQuery()方法获取查询语句对应的Query对象。

    修改Employee.hbm.xml

     1 <?xml version="1.0"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4 <!-- Generated 2017-6-9 23:13:49 by Hibernate Tools 3.5.0.Final -->
     5 <hibernate-mapping>
     6     <class name="com.dx.hibernate09.hql01.Employee" table="DX_EMPLOYEE">
     7         。。。
     8     </class>
     9     <query name="queryWithSalaryScope">
    10     <![CDATA[From Employee e Where e.salary>:minSalary and e.salary<:maxSalary]]>
    11     </query>
    12 </hibernate-mapping>

    测试函数

     1     @Test
     2     public void testHQLPageQuery() {
     3         String hql = "From Employee";
     4 
     5         int pageNum = 1;
     6         int pageSize = 10;
     7         Query query = session.createQuery(hql).setFirstResult((pageNum - 1) * pageSize).setMaxResults(pageSize);
     8 
     9         List<Employee> employees = query.list();
    10         System.out.println(employees.size());
    11         System.out.println(employees);
    12     }

    执行sql及结果

     1 Hibernate: 
     2     select
     3         employee0_.ID as ID1_1_,
     4         employee0_.NAME as NAME2_1_,
     5         employee0_.SALARY as SALARY3_1_,
     6         employee0_.EMAIL as EMAIL4_1_,
     7         employee0_.DEPARTMENT_ID as DEPARTME5_1_ 
     8     from
     9         DX_EMPLOYEE employee0_ 
    10     where
    11         employee0_.SALARY>? 
    12         and employee0_.SALARY<?
    13 4
    14 [Employee [id=7, name=tommy6, salary=6000.0, email=tommy6@dx.com]
    15 , Employee [id=8, name=tommy7, salary=7000.0, email=tommy7@dx.com]
    16 , Employee [id=9, name=tommy8, salary=8000.0, email=tommy8@dx.com]
    17 , Employee [id=10, name=tommy9, salary=9000.0, email=tommy9@dx.com]
    18 ]

    HQL投影查询

    1)投影查询:查询结果仅包含实体的部分属性。通过SELECT关键字实现。

    2)Query的list()方法返回的结果集中包含的是数组类型的元素,每个对象数组代表查询结果的一条记录。

    3)可以在持久化类中定义一个对象的构造器来包装投影查询返回的记录,是程序代码能完成运用面向对象的语义来访问查询结果集。

    4)可以通过DISTINCT关键字来保证查询结果不会返回重复元素。

    返回数据测试:

     1     @Test
     2     public void testHQLFileds() {
     3         String hql = "Select e.email,e.salary,e.department From Employee e Where e.salary>:salary and e.department=:department";
     4         Department department = new Department();
     5         department.setId(3);
     6         Query query = session.createQuery(hql).setFloat("salary", 10000).setEntity("department", department);
     7 
     8         List<Object[]> result = query.list();
     9 
    10         for (Object[] item : result) {
    11             System.err.println(Arrays.asList(item));
    12         }
    13     }

    执行sql语句及结果:

     1 Hibernate: 
     2     select
     3         employee0_.EMAIL as col_0_0_,
     4         employee0_.SALARY as col_1_0_,
     5         employee0_.DEPARTMENT_ID as col_2_0_,
     6         department1_.ID as ID1_0_,
     7         department1_.NAME as NAME2_0_ 
     8     from
     9         DX_EMPLOYEE employee0_ 
    10     inner join
    11         DX_DEPARTMENT department1_ 
    12             on employee0_.DEPARTMENT_ID=department1_.ID 
    13     where
    14         employee0_.SALARY>? 
    15         and employee0_.DEPARTMENT_ID=?
    16 [tommy12@dx.com, 12000.0, Department [id=3, name=业务部门]]
    17 [tommy17@dx.com, 17000.0, Department [id=3, name=业务部门]]
    18 [tommy22@dx.com, 22000.0, Department [id=3, name=业务部门]]
    19 [tommy27@dx.com, 27000.0, Department [id=3, name=业务部门]]
    20 [tommy32@dx.com, 32000.0, Department [id=3, name=业务部门]]
    21 [tommy37@dx.com, 37000.0, Department [id=3, name=业务部门]]
    22 [tommy42@dx.com, 42000.0, Department [id=3, name=业务部门]]
    23 [tommy47@dx.com, 47000.0, Department [id=3, name=业务部门]]
    24 [tommy52@dx.com, 52000.0, Department [id=3, name=业务部门]]
    25 [tommy57@dx.com, 57000.0, Department [id=3, name=业务部门]]
    26 [tommy62@dx.com, 62000.0, Department [id=3, name=业务部门]]
    27 [tommy67@dx.com, 67000.0, Department [id=3, name=业务部门]]
    28 [tommy72@dx.com, 72000.0, Department [id=3, name=业务部门]]
    29 [tommy77@dx.com, 77000.0, Department [id=3, name=业务部门]]

    上边我们看到如果返回数据,用起来多少会有点不爽,是可以在持久化类中定义一个对象的构造器来包装投影查询返回的记录,是程序代码能完成运用面向对象的语义来访问查询结果集。

    修改上边的代码:

     1     @Test
     2     public void testHQLFileds_() {
     3         String hql = "Select new Employee(e.email,e.salary,e.department) From Employee e Where e.salary>:salary and e.department=:department";
     4         Department department = new Department();
     5         department.setId(3);
     6         Query query = session.createQuery(hql).setFloat("salary", 10000).setEntity("department", department);
     7 
     8         List<Employee> result = query.list();
     9 
    10         for (Employee item : result) {
    11             System.err.println(item.getId() + "," + item.getEmail() + "," + item.getSalary() + "," + item.getDepartment());
    12         }
    13     }

    执行sql及结果:

     1 Hibernate: 
     2     select
     3         employee0_.EMAIL as col_0_0_,
     4         employee0_.SALARY as col_1_0_,
     5         employee0_.DEPARTMENT_ID as col_2_0_ 
     6     from
     7         DX_EMPLOYEE employee0_ 
     8     inner join
     9         DX_DEPARTMENT department1_ 
    10             on employee0_.DEPARTMENT_ID=department1_.ID 
    11     where
    12         employee0_.SALARY>? 
    13         and employee0_.DEPARTMENT_ID=?
    14 Hibernate: 
    15     select
    16         department0_.ID as ID1_0_0_,
    17         department0_.NAME as NAME2_0_0_ 
    18     from
    19         DX_DEPARTMENT department0_ 
    20     where
    21         department0_.ID=?
    22 null,tommy12@dx.com,12000.0,Department [id=3, name=业务部门]
    23 null,tommy17@dx.com,17000.0,Department [id=3, name=业务部门]
    24 null,tommy22@dx.com,22000.0,Department [id=3, name=业务部门]
    25 null,tommy27@dx.com,27000.0,Department [id=3, name=业务部门]
    26 null,tommy32@dx.com,32000.0,Department [id=3, name=业务部门]
    27 null,tommy37@dx.com,37000.0,Department [id=3, name=业务部门]
    28 null,tommy42@dx.com,42000.0,Department [id=3, name=业务部门]
    29 null,tommy47@dx.com,47000.0,Department [id=3, name=业务部门]
    30 null,tommy52@dx.com,52000.0,Department [id=3, name=业务部门]
    31 null,tommy57@dx.com,57000.0,Department [id=3, name=业务部门]
    32 null,tommy62@dx.com,62000.0,Department [id=3, name=业务部门]
    33 null,tommy67@dx.com,67000.0,Department [id=3, name=业务部门]
    34 null,tommy72@dx.com,72000.0,Department [id=3, name=业务部门]
    35 null,tommy77@dx.com,77000.0,Department [id=3, name=业务部门]

    HQL报表查询

    报表查询用于对数据分组和统计,与SQL一样,HQL利用GROUP BY关键字对数据分组,用HAVING关键字对分组数据设定约束条件。

    在HQL查询语句中可以调用以下聚合函数:

    1. count()
    2. min()
    3. max()
    4. sum()
    5. avg()

    测试代码

        @Test
        public void testGroupBy() {
            String hql = "Select min(e.salary),max(e.salary) " 
                    + "From Employee e " 
                    + "group by e.department having(min(e.salary)>:minSalary)";
            Query query = session.createQuery(hql).setFloat("minSalary", 0);
    
            List<Object[]> result = query.list();
            for (Object[] item : result) {
                System.out.println(Arrays.asList(item));
            }
        }

    执行sql与结果

     1 Hibernate: 
     2     select
     3         min(employee0_.SALARY) as col_0_0_,
     4         max(employee0_.SALARY) as col_1_0_ 
     5     from
     6         DX_EMPLOYEE employee0_ 
     7     group by
     8         employee0_.DEPARTMENT_ID 
     9     having
    10         min(employee0_.SALARY)>?
    11 [1000.0, 76000.0]
    12 [2000.0, 77000.0]
    13 [3000.0, 78000.0]
    14 [4000.0, 79000.0]
  • 相关阅读:
    Android 的快速增长让一些开发人员担忧 狼人:
    Android程序开发入门教程 狼人:
    2010:Android 商机之年 狼人:
    控制力的较量 Android上的博弈 狼人:
    深度解析Windows Phone 7 开发 狼人:
    图解iPhone开发入门教程 狼人:
    用Android LiveCD体验Android 操作系统的魅力 狼人:
    Android 教程之实现动作感应技术 狼人:
    Android版多功能日历,欢迎大家测试 狼人:
    iPhone、Windows Mobile、Symbian、Android移动开发前景分析 狼人:
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/6978334.html
Copyright © 2011-2022 走看看