Hibernate提供了以下几种检索对象的方式
--导航对象图检索方式:根据已经加载的对象导航。
--OID检索方式:按照对象的OID来检索对象。
--HQL检索方式:使用面向对象的HQL查询语言
--QBC检索方式:使用QBC(Query By Criteria) API来检索对象,
这种API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口。
--离线条件查询
--本地SQL检索方式:使用本地数据库的SQL查询语句。
===============================================
HQL(Hibernate Query Language)是面向对象的查询语言,它和SQL查询语言有些相似,
在HIbernate提供的各种检索方式中,HQL是使用最广的一种检索方式,它有如下功能:
--在查询语句中设定各种查询条件
--支持投影查询,即仅检索出对象的部分属性
--支持分页查询
--支持连接查询
--支持分组查询,允许使用HAVING和GROUP BY关键字
--提供内置聚集函数,如sum(),min()和max()
--支持子查询
--支持动态绑定参数
--能够调用用户定义的SQL函数或标准函数。
HQL检索方式(1)
HQL检索方式包括以下步骤
--通过Session的createQuery()方法构建一个Query对象,它包括一个HQL查询语句,
HQL查询语句中可以包含命名参数
--动态绑定参数
--调用Query相关方法执行查询语句,Query接口支持方法链编程风格,
它的setXxx()方法返回实例本身,而不是void类型。
HQL与SQL比较
--HQL查询语句是面向对象的,Hibernate负责解析HQL查询语句,然后根据
对象-关系映射文件中的映射信息,把HQL查询语句翻译成相应的SQL语句,
HQL查询语句中的主体是域模型中的类及类的属性
--SQL查询语句与关系数据库绑定在一起的,SQL查询语句中主体是数据库表及表的字段。
绑定参数:
--Hibernate的参数机制依赖于JDBC API中的PreparedStatement
的预定义SQL语句功能。
=====================================================================
HQL的参数绑定由两种形式:
*按参数名字绑定:在HQL查询语句中定义命名参数,命名参数以“:”开头,
*按参数位置绑定:在HQL查询语句中用“?”来定义参数位置。
--相关方法:
*setEntity():把参数与一个持久化类绑定
*setParameter():绑定任意类型的参数,该方法的第三个参数
显式指定Hibernate映射类型。
--HQL采用ORDER BY关键字对查询结果排序。
在映射文件中定义命名查询语句
--Hibernate允许在映射文件中定义字符串形式的查询语句。
--<query>元素用于定义一个HQL查询语句,它和<class>元素并列
<query name="salaryEmps">
<![CDATA[
From Employee a WHERE e.salary > :minSal And e.salary < :maxSal
]]
</query>
--在程序中通过Session的getNamedQuery()方法获取查询语句对应的Query对象。
命名参数查询允许我们将HQL语句写在*.hbm.xml中。
=====================================================================
投影查询:
--查询结果仅包含实体的部分属性,通过SELECT关键字实现。
--Query的list()方法返回的集合中包含的是数组类型的元素,
每个对象数组代表查询结果的一条记录
@Test
public void testFieldQuery(){
String hql = "SELECT e.email, e.salary, e.dept FROM Employee e WHERE e.dept = :dept";
Query query = session.createQuery(hql);
Department dept = new Department();
dept.setId(80);
List<Object[]> result = query.setEntity("dept",dept);
for(Object[] objs : result){
System.out.println(Arrays.asList(objs));
}
}
--可以在持久化类中定义一个对象的构造器来包装投影查询
返回的记录,使程序代码能完全运用面向对象的语义来访问查询结果集。
@Test
public void testFieldQuery(){
/**
*对应的实体类Employee中需要无参构造器,和与HQL语句中对象构造器
*传入的参数对应的构造器。
*/
String hql = "SELECT new Employee(e.email,e.salary,e.dept)"+
+"FROM Employee e "
+"WHERE e.dept = :dept";
Query query = session.createQuery(hql);
Department dept = new Department();
dept.setId(80);
List<Employee> result = query.setEntity("dept",dept);
for(Employee emp : result){
System.out.println(emp.getId()+","+emp.getEmail);
}
}
--可以通过DISTINCT关键字来保证查询结果不会返回重复元素。
=========================================================
离线查询
--离线查询就是建立一个DetachedCriteria对象,将查询的条件等指定好,然后在
session.beginTransaction()后将这个对象传入。通常这个对象可以在表示层建
立,然后传入业务层进行查询。
示例:
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class);
detachedCriteria.add(Restrictions.eq("name","ijse");
Session session = SessionFactory.getCurrentSession();
User user = new User();
Transaction ts = session.beginTransaction();
try {
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
user= (User) criteria.list().get(0);
session.commit();
}catch (HibernateException ex) {
ts.rollBack();
ex.printStackTrace();
}
System.out.println(user.getName());
==========================================================
报表查询
报表查询用于对数据分组和统计,与SQL一样,HQL利用GROUP BY 关键字对数据分组,用HAVING关键字对分组数据设定约束条件。
在HQL查询语句中可以调用以下聚集函数
--count()
--min()
--max()
--sum()
--avg()
===========================================================
HQL(迫切)左外连接
*迫切左外连接:
--LEFT JOIN FETCH关键字表示迫切左外连接检索策略。
--list()方法返回的集合中存放实体对象的引用,每个Department对象关联
的Employee集合都被初始化,存放所有关联的Employee的实体对象。
-查询结果中可能会包含重复元素,可以通过一个HashSet来过滤重复元素。
左外连接:
--LEFT JOIN 关键字表示左外连接查询。
--list()方法返回的集合中存放的是对象数组类型。
--根据配置文件来决定Employee集合的检索策略。
--如果希望list()方法返回的集合中仅包含Department对象,可以HQL查询
语句中使用SELECT关键字
============================================================
关联级别运行时的检索策略
--如果在HQL中没有显示指定检索策略,将使用映射文件配置的检索策略。
--HQL会忽略映射文件中设置的迫切左外连接检索策略,如果希望
HQL采用迫切左外连接策略,就必须在HQL查询语句中显式的指定它。
--若在HQL代码中显式指定了检索策略,就会覆盖映射文件中配置的检索
策略。