[原创]java WEB学习笔记90:Hibernate学习之路-- -HQL检索方式,分页查询,命名查询语句,投影查询,报表查询
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用
内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。
本人互联网技术爱好者,互联网技术发烧友
微博:伊直都在0221
QQ:951226918
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Employee
1 package com.jason.hibernate.entities.HQL;
2
3 public class Employee {
4
5 private Integer id;
6 private String name;
7 private float salary;
8 private String email;
9
10 private Department dept;
11
12 public Integer getId() {
13 return id;
14 }
15
16 public void setId(Integer id) {
17 this.id = id;
18 }
19
20 public String getName() {
21 return name;
22 }
23
24 public void setName(String name) {
25 this.name = name;
26 }
27
28 public float getSalary() {
29 return salary;
30 }
31
32 public void setSalary(float salary) {
33 this.salary = salary;
34 }
35
36 public String getEmail() {
37 return email;
38 }
39
40 public void setEmail(String email) {
41 this.email = email;
42 }
43
44 public Department getDept() {
45 return dept;
46 }
47
48 public void setDept(Department dept) {
49 this.dept = dept;
50 }
51
52 @Override
53 public String toString() {
54 return "Employee [id=" + id + ", name=" + name + ", salary=" + salary
55 + ", email=" + email + ", dept=" + dept + "]";
56 }
57
58
59 }
Department
1 package com.jason.hibernate.entities.HQL;
2
3 import java.util.HashSet;
4 import java.util.Set;
5
6 public class Department {
7
8 private Integer id;
9 private String name;
10
11 private Set<Employee> emps = new HashSet<>();
12
13 public Integer getId() {
14 return id;
15 }
16
17 public void setId(Integer id) {
18 this.id = id;
19 }
20
21 public String getName() {
22 return name;
23 }
24
25 public void setName(String name) {
26 this.name = name;
27 }
28
29 public Set<Employee> getEmps() {
30 return emps;
31 }
32
33 public void setEmps(Set<Employee> emps) {
34 this.emps = emps;
35 }
36
37 }
Department.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 2016-10-6 19:46:22 by Hibernate Tools 3.4.0.CR1 -->
5
6 <hibernate-mapping package="com.jason.hibernate.entities.HQL">
7
8 <class name="Department" table="GG_DEPARTMENT">
9
10 <id name="id" type="java.lang.Integer">
11 <column name="ID" />
12 <generator class="native" />
13 </id>
14
15 <property name="name" type="java.lang.String">
16 <column name="NAME" />
17 </property>
18
19 <set name="emps" table="GG_EMPLOYEE" inverse="true" lazy="true">
20 <key>
21 <column name="DEPT_ID" />
22 </key>
23 <one-to-many class="Employee" />
24 </set>
25
26 </class>
27 </hibernate-mapping>
Employee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-10-6 19:46:22 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="com.jason.hibernate.entities.HQL">
<class name="Employee" table="GG_EMPLOYEE">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="salary" type="float">
<column name="SALARY" />
</property>
<property name="email" type="java.lang.String">
<column name="EMAIL" />
</property>
<many-to-one name="dept" class="Department" fetch="join">
<column name="DEPT_ID" />
</many-to-one>
</class>
</hibernate-mapping>
HibernateTest
1 package com.jason.hibernate.entities.HQL;
2
3 import java.util.List;
4
5 import org.hibernate.Query;
6 import org.hibernate.Session;
7 import org.hibernate.SessionFactory;
8 import org.hibernate.Transaction;
9 import org.hibernate.cfg.Configuration;
10 import org.hibernate.service.ServiceRegistry;
11 import org.hibernate.service.ServiceRegistryBuilder;
12 import org.junit.After;
13 import org.junit.Before;
14 import org.junit.Test;
15
16 public class HibernateTest {
17
18 private SessionFactory sessionFactory;
19 private Session session;
20 private Transaction transaction;
21
22 // 创建上述三个对象
23 @Before
24 public void init() {
25 Configuration configuration = new Configuration().configure();
26 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
27 .applySettings(configuration.getProperties())
28 .buildServiceRegistry();
29
30 sessionFactory = configuration.buildSessionFactory(serviceRegistry);
31
32 session = sessionFactory.openSession();
33
34 transaction = session.beginTransaction();
35 }
36
37 // 关闭上述三个对象
38 @After
39 public void destroy() {
40 transaction.commit();
41 session.close();
42 sessionFactory.close();
43 }
44
45 }
测试方法
1. 分页查询:
1)setFirstResult(int firstResult): 设定从哪一个对象开始检索, 参数 firstResult 表示这个对象在查询结果中的索引位置, 索引位置的起始值为 0. 默认情况下, Query 从查询结果中的第一个对象开始检索
2)setMaxResults(int maxResults): 设定一次最多检索出的对象的数目. 在默认情况下, Query 和 Criteria 接口检索出查询结果中所有的对象
1 @Test
2 public void testPageQuery(){
3 String hql = "FROM Employee";
4 Query query = session.createQuery(hql);
5
6 int pageNo = 3;
7 int pageSize = 5;
8
9
10 List<Employee> emps =query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
11
12 for(Employee emp : emps){
13 System.out.println(emp);
14
15 }
16
17 }
2.命名查询语句
1)Hibernate 允许在映射文件中定义字符串形式的查询语句
2)<query> 元素用于定义一个 HQL 查询语句, 它和 <class> 元素并列.
3)在程序中通过 Session 的 getNamedQuery() 方法获取查询语句对应的 Query 对象.
在employee.hbm.xml 中添加如下命名
1 <!-- 命名查询 -->
2 <query name="salaryEmps"><![CDATA[FROM Employee e WHERE e.salary > :minSal AND e.salary < :maxSal]]> </query>
测试
1 @Test
2 public void testNamedQuery(){
3
4 Query query = session.getNamedQuery("salaryEmps");
5 List<Employee> emps = query.setFloat("minSal", 5000).setFloat("maxSal", 10000).list();
6 System.out.println(emps.size());
7
8 }
3.投影查询
1)投影查询: 查询结果仅包含实体的部分属性. 通过 SELECT 关键字实现.
2)Query 的 list() 方法返回的集合中包含的是数组类型的元素, 每个对象数组代表查询结果的一条记录
3)可以在持久化类中定义一个对象的构造器来包装投影查询返回的记录, 使程序代码能完全运用面向对象的语义来访问查询结果集.
4)可以通过 DISTINCT 关键字来保证查询结果不会返回重复元素
方式一:
1 @Test
2 public void testFieldQuery(){
3
4 String hql = "SELECT e.email, e.salary FROM Employee e WHERE e.dept = :dept";
5 Query query = session.createQuery(hql);
6
7 Department dept = new Department();
8 dept.setId(80);
9 List<Object[]> result = query.setEntity("dept", dept).list();
10
11 for(Object[] objs : result){
12 System.out.println(Arrays.asList(objs));
13 }
14
15 }
方式二:推荐
① 将返回的属性,在持久化类中封装返回属性的构造器,按照属性定义的顺序
② 结果返回给 一个list<entity> 的集合
③ 通过遍历集合,输出值
测试方法
1 @Test
2 public void testFieldQuery(){
3
4 String hql = "SELECT new Employee(e.email, e.salary, e.dept) FROM Employee e WHERE e.dept = :dept";
5 Query query = session.createQuery(hql);
6
7 Department dept = new Department();
8 dept.setId(80);
9 List<Employee> result = query.setEntity("dept", dept).list();
10
11 for(Employee emp : result){
12 System.out.println(emp.getId() + "," + emp.getEmail() + "," + emp.getSalary() + "," + emp.getDept());
13 }
14
15 }
在Employee 持久化类中增加一个特定的构造器
1 public Employee(String email, float salary, Department dept) {
2 super();
3 this.salary = salary;
4 this.email = email;
5 this.dept = dept;
6 }
4.报表查询:
1)报表查询用于对数据分组和统计, 与 SQL 一样, HQL 利用 GROUP BY 关键字对数据分组, 用 HAVING 关键字对分组数据设定约束条件.
2)在 HQL 查询语句中可以调用以下聚集函数:count() min() max() sum() avg()
1 @Test
2 public void testGroupBy(){
3
4 String hql = "SELECT min(e.salary) , max(e.salary)"
5 + "FROM Employee e "
6 + "GROUP BY e.dept "
7 + "HAVING min(e.salary) > :minSal";
8
9
10 Query query = session.createQuery(hql).setFloat("minSal", 5000);
11 List<Object[]> result = query.list();
12 for(Object[] objs : result){
13 System.out.println(Arrays.asList(objs));
14 }
15
16 }