Hibernate中提供了多种检索对象的方式,主要包括以下种类:
本文主要介绍第三种方式,也就是HQL检索对象。
HQL(Hibernate Query Language)是面向对象的查询语言,它和SQL查询语言有些相似。在Hibernate提供的各种检索方式中,HQL是使用最广的一种检索方式。它有如下功能:
HQL检索方式包括以下步骤:
Query接口支持方法链编程风格,它的setXxx()方法返回自身实例,而不是void类型。
HQL vs SQL:
绑定参数:
1.按参数名字绑定:在HQL查询语句中定义命名参数,命名参数以":"开头
2.按参数位置绑定:在HQL查询语句中用"?"来定义参数位置
1.setEntity():把参数与一个持久化类绑定
2.setParameter(): 绑定任意类型的参数,该方法的第三个参数显式指定Hibernate映射类型
下面详细介绍下Hibernate的HQL的几个功能:
分页查询:
在映射文件中定义命名查询语句
<query name="salaryEmps"><![CDATA[FROM Employee w WHERE e.salary > :minSal AND e.salary < :maxSal]]></query>
投影查询
报表查询
HQL(迫切)左外连接
查询结果中可能会包含重复元素,可以通过一个HashSet来过滤重复元素
HQL(迫切)内连接
关联级别运行时的检索策略:
==============================代码区========================================
Department.java
1 package com.yl.hibernate.entities; 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<Employee>(); 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 @Override 38 public String toString() { 39 //return "Department [id=" + id + ", name=" + name + "]"; 40 return "Department [id=" + id + "]"; 41 } 42 43 }
Employee.java
1 package com.yl.hibernate.entities; 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 + "]"; 55 } 56 57 public Employee(){} 58 59 public Employee(String email, float salary, Department dept) { 60 super(); 61 this.salary = salary; 62 this.email = email; 63 this.dept = dept; 64 } 65 66 }
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 2014-12-1 19:29:32 by Hibernate Tools 3.4.0.CR1 --> 5 <hibernate-mapping> 6 <class name="com.yl.hibernate.entities.Department" table="YL_DEPARTMENT"> 7 <id name="id" type="java.lang.Integer"> 8 <column name="ID" /> 9 <generator class="native" /> 10 </id> 11 <property name="name" type="java.lang.String"> 12 <column name="NAME" /> 13 </property> 14 <set name="emps" table="YL_EMPLOYEE" inverse="true" lazy="true"> 15 <key> 16 <column name="DEPT_ID" /> 17 </key> 18 <one-to-many class="com.yl.hibernate.entities.Employee" /> 19 </set> 20 </class> 21 </hibernate-mapping>
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 2014-12-1 19:29:32 by Hibernate Tools 3.4.0.CR1 --> 5 <hibernate-mapping> 6 <class name="com.yl.hibernate.entities.Employee" table="YL_EMPLOYEE"> 7 <id name="id" type="java.lang.Integer"> 8 <column name="ID" /> 9 <generator class="native" /> 10 </id> 11 <property name="name" type="java.lang.String"> 12 <column name="NAME" /> 13 </property> 14 <property name="salary" type="float"> 15 <column name="SALARY" /> 16 </property> 17 <property name="email" type="java.lang.String"> 18 <column name="EMAIL" /> 19 </property> 20 <many-to-one name="dept" class="com.yl.hibernate.entities.Department" fetch="join"> 21 <column name="DEPT_ID" /> 22 </many-to-one> 23 </class> 24 25 <query name="salaryEmps"><![CDATA[FROM Employee e WHERE e.salary > :minSal AND e.salary < :maxSal]]></query> 26 27 </hibernate-mapping>
测试类:
1 package com.yl.hibernate.test; 2 3 4 import java.util.ArrayList; 5 import java.util.Arrays; 6 import java.util.LinkedHashSet; 7 import java.util.List; 8 import java.util.Set; 9 10 import oracle.net.aso.e; 11 12 import org.hibernate.Query; 13 import org.hibernate.Session; 14 import org.hibernate.SessionFactory; 15 import org.hibernate.Transaction; 16 import org.hibernate.cfg.Configuration; 17 import org.hibernate.service.ServiceRegistry; 18 import org.hibernate.service.ServiceRegistryBuilder; 19 import org.junit.After; 20 import org.junit.Before; 21 import org.junit.Test; 22 23 import com.yl.hibernate.entities.Department; 24 import com.yl.hibernate.entities.Employee; 25 26 public class HibernateTest { 27 28 private SessionFactory sessionFactory; 29 private Session session; 30 private Transaction transaction; 31 32 @Before 33 public void init() { 34 Configuration configuration = new Configuration().configure(); 35 ServiceRegistry serviceRegistry = 36 new ServiceRegistryBuilder().applySettings(configuration.getProperties()) 37 .buildServiceRegistry(); 38 39 sessionFactory = configuration.buildSessionFactory(serviceRegistry); 40 41 session = sessionFactory.openSession(); 42 43 transaction = session.beginTransaction(); 44 } 45 @After 46 public void destory() { 47 transaction.commit(); 48 49 session.close(); 50 51 sessionFactory.close(); 52 } 53 54 @Test 55 public void testHQL() { 56 //1.创建 Query 对象 57 //基于位置参数 58 String hql = "FROM Employee e WHERE e.salary > ? AND e.email LIKE ? AND e.dept = ? ORDER BY e.salary"; 59 Query query = session.createQuery(hql); 60 //2.绑定参数 61 //Query 对象调用setXxx()方法支持方法链的编程风格 62 Department dept = new Department(); 63 dept.setId(30); 64 query.setFloat(0, 2000) 65 .setString(1, "%A%") 66 .setEntity(2, dept); 67 //3.执行查询 68 List<Employee> emps = query.list(); 69 System.out.println(emps); 70 } 71 72 @Test 73 public void testHQLNamedParameter() { 74 //1.创建 Query 对象 75 //基于命名参数 76 String hql = "FROM Employee e WHERE e.salary > :sal AND e.email LIKE :email"; 77 Query query = session.createQuery(hql); 78 //2.绑定参数 79 query.setFloat("sal", 2000) 80 .setString("email", "%A%"); 81 //3.执行查询 82 List<Employee> emps = query.list(); 83 System.out.println(emps.size()); 84 } 85 /** 86 * 分页查询 87 */ 88 @Test 89 public void testPageQuery() { 90 String hql = "FROM Employee"; 91 Query query = session.createQuery(hql); 92 93 int pageNo = 3; 94 int pageSize = 5; 95 96 List<Employee> employees = query.setFirstResult((pageNo-1) * pageSize) 97 .setMaxResults(pageSize) 98 .list(); 99 System.out.println(employees); 100 101 } 102 /** 103 * 在映射文件中定义命名查询语句 104 */ 105 @Test 106 public void testNamedQuery() { 107 Query query = session.getNamedQuery("salaryEmps"); 108 109 List<Employee> emps = query.setFloat("minSal", 2000) 110 .setFloat("maxSal", 3000) 111 .list(); 112 System.out.println(emps); 113 114 } 115 /** 116 * 投影查询 117 */ 118 @Test 119 public void testFieldQuery() { 120 String hql = "SELECT e.email, e.salary, e.dept FROM Employee e WHERE e.dept = :dept"; 121 Query query = session.createQuery(hql); 122 123 Department dept = new Department(); 124 dept.setId(20); 125 List<Object[]> result = query.setEntity("dept", dept).list(); 126 127 for (Object[] objects : result) { 128 System.out.println(Arrays.asList(objects)); 129 } 130 131 } 132 133 /** 134 * 投影查询 135 */ 136 @Test 137 public void testFieldQuery2() { 138 String hql = "SELECT new Employee(e.email, e.salary, e.dept) " 139 + "FROM Employee e " 140 + "WHERE e.dept = :dept"; 141 142 Query query = session.createQuery(hql); 143 144 Department dept = new Department(); 145 dept.setId(20); 146 List<Employee> result = query.setEntity("dept", dept).list(); 147 148 for (Employee emp : result) { 149 System.out.println(emp.getId() + ", " + emp.getEmail() + ", " + emp.getSalary() + ", " + emp.getDept()); 150 } 151 152 } 153 154 @Test 155 public void testGroupBy() { 156 String hql = "SELECT min(e.salary), max(e.salary) " 157 + "FROM Employee e " 158 + "GROUP BY e.dept " 159 + "HAVING min(salary) > :minSal"; 160 Query query = session.createQuery(hql) 161 .setFloat("minSal", 700); 162 163 List<Object[]> result = query.list(); 164 for (Object[] objects : result) { 165 System.out.println(Arrays.asList(objects)); 166 } 167 } 168 /** 169 * 迫切左外连接 170 */ 171 @Test 172 public void testLeftJoinFetch() { 173 /*String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps"; 174 Query query = session.createQuery(hql); 175 176 List<Department> depts = query.list(); 177 System.out.println(depts.size());*/ 178 179 String hql = "FROM Department d LEFT JOIN FETCH d.emps"; 180 Query query = session.createQuery(hql); 181 182 List<Department> depts = query.list(); 183 depts = new ArrayList<Department>(new LinkedHashSet<Department>(depts)); 184 185 System.out.println(depts.size()); 186 187 for (Department department : depts) { 188 System.out.println(department.getName() + "-" + department.getEmps().size()); 189 } 190 } 191 192 @Test 193 public void testLeftJoin() { 194 /*String hql = "FROM Department d LEFT JOIN d.emps"; 195 Query query = session.createQuery(hql); 196 197 List<Object[]> result = query.list(); 198 System.out.println(result); 199 200 for (Object[] objects : result) { 201 System.out.println(Arrays.asList(objects)); 202 }*/ 203 204 String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps"; 205 Query query = session.createQuery(hql); 206 207 List<Department> depts = query.list(); 208 System.out.println(depts.size()); 209 210 for (Department department : depts) { 211 System.out.println(department.getName() + ", " + department.getEmps().size()); 212 } 213 } 214 215 @Test 216 public void testInnerJoinFetch() { 217 /*String hql = "SELECT DISTINCT d FROM Department d INNER JOIN FETCH d.emps"; 218 Query query = session.createQuery(hql); 219 220 List<Department> depts = query.list(); 221 System.out.println(depts.size());*/ 222 223 String hql = "FROM Department d INNER JOIN FETCH d.emps"; 224 Query query = session.createQuery(hql); 225 226 List<Department> depts = query.list(); 227 depts = new ArrayList<Department>(new LinkedHashSet<Department>(depts)); 228 229 System.out.println(depts.size()); 230 231 for (Department department : depts) { 232 System.out.println(department.getName() + "-" + department.getEmps().size()); 233 } 234 } 235 236 @Test 237 public void testInnerJoin() { 238 /*String hql = "FROM Department d INNER JOIN d.emps"; 239 Query query = session.createQuery(hql); 240 241 List<Object[]> result = query.list(); 242 System.out.println(result); 243 244 for (Object[] objects : result) { 245 System.out.println(Arrays.asList(objects)); 246 }*/ 247 248 String hql = "SELECT DISTINCT d FROM Department d INNER JOIN d.emps"; 249 Query query = session.createQuery(hql); 250 251 List<Department> depts = query.list(); 252 System.out.println(depts.size()); 253 254 for (Department department : depts) { 255 System.out.println(department.getName() + ", " + department.getEmps().size()); 256 } 257 } 258 259 }