4.6 Hibernate 查询体系
Hibernate 提供了异常强大的查询体系,有多种查询方式可以供我们使用。如Hibernate 的 HQL 查询或者使用条件查询,甚至可以使用原生的 SQL 查询语句等。另外还提供了一种数据过滤功能,这些都用于筛选目标数据。
下面分别介绍 Hibernate 的四种数据筛选方法
4.6.1 HQL 查询(1)
HQL 是 HibernateQuery Language 的缩写, HQL 的语法很像 SQL 的语法,但 HQL是一种面向对象的查询语言。因此, SQL 的操作对象是数据表和列等数据对象:而HQL的操作对象是类、实例和属性等。
HQL 是完全面向对象的查询语言,因此可以支持继承和多态等特征。
HQL 查询依赖于 Query 类,每个 Query 实例对应一个查询对象,使用 HQL 查询按如下步骤进行:
(1)获取 Hibernate Session对象:
(2) 编写 HQL 语句:
(3)以 HQL 语句作为参数,调用 Session 的 createQuery方法创建查询对象:
(4) 如果 HQL 语句包含参数,调用 Query 的 setXxx 方法为参数赋值:
(5) 调用 Query 对象的 list 等方法遍历查询结果。
看下面的查询示例:
public class HqlQuery { public static void main(String[] args) throws Exception { HqlQuery mgr = new HqlQuery(); /I调用查询方法 mgr.findPersons(}; //调用第二个查询方法 mgr.findPersonsByHappenDate();HibernateUtil.sessionFactory.close(); //第一个查询方法 private void findPersons() //获得 HibernateSessionSession sess = HibernateUtil.currentSession(); //开始事务 Transaction tx=sess.beginTransaction(); //以 HQL语句创建Query对象 //执行 setString方法为 HQL语旬的参数赋值 //Query调用 list 方法访问查询的全部实例 List pl = sess.createQuery("from Person p where p . myEvents.title = :eventTitle") .setString("eventTitle","很普通事情") .list(); ll:i!!i历查询的全部结果 for (Iterator pit = pl.iterator() ; pit.hasNext(); ) Person p = ( Person )pit.next();System.out.println(p.getName(); //提交事务 tx.commit();HibernateUtil.closeSession(); //第二个查询方法 private void findPersonsByHappenDate() throws Exception //获得 Hibernate Session对象 Session sess = HibernateUtil.currentSession();Transaction tx = sess.beginTransaction(); //解析出 Date对象SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd");Date start = sdf.parse("2005-01-01"); System.out.println("系统开始通过日期查找人"+start); //通过 Session的 createQuery方法创建Query对象 //设置参数 //返回结果集 List pl = sess.createQuery("from Person p where p. myEvents.happenDate between :firstDate and :endDate").setDate("firstDate",start).setDate("endDate",new Date(? .1ist() ; ll:i!!i历结果集for(iteratorpit = pl.iterator() ; pit.hasNext(); ) Person p = ( Person )pit.next();System.out.println(p.getName(); } tx.commit();HibernateUtil.closeSession(); |
通过上面的示例程序,可看出其查询步骤基本相似,但Query对象可以连续多次设置参数,这得益于HibernateQuery的设计。
通常的 seαxx 方法返回值都是void,ill HibernateQuery 的 setXxx 方法返回值是Query 本身。因此,程序通过 Session 创建 Query 后,多次直接调用 setXxx 方法为 HQL语句的参数赋值,再直接调用 list 方法返回查询到的全部结果。
Query 还包含两个方法。
setFirstResult(intfirstResult): 设置返回的结果集从第几条记录开始。
setMaxResults(int maxResults): 设置本次查询返回的结果数。
这两个方法用于实现Hibernate分页。
下面简单介绍 HQL 语句的语法。
HQL 语句本身不区分大小写,也就是说: HQL 语句的关键宇及函数都不区分大小写。但 HQL语句中所使用的包名、类名、实例名及属性名都区分大小写。
1.from 子句
from 是最简单也是最基本的HQL语旬, from关键字后紧跟持久化类的类名。例如:
表明从Person持久化类中选出全部的实例。
大部分时候,推荐为该Person的每个实例另起别名。例如:
2. select子句
select字句用于确定选择出的属性,当然select选择的属性必须是from后持久化类包含的属性,例如:
select p.name from Person as p |
select 可以选择任意属性,不仅可以选择持久化类的直接属性,还可以选择引用属性包含的属性,例如:
select p.name.firstName from Person as p
|
select 也支持将选择出的属性存入一个List 对象中,例如:
select new list(p.name, p.address) from Person as p
|
另外, select 甚至可以将选择出的属性直接封装成对象,例如:
select new ClassTest(p.name , p.address) from Person as p |
前提是 ClassTest 支持 p.name 及 p.address 的构造器。假如 p.name 的数据类型是String, p.address 的数据类型是 String,则 ClassTest必须有如下的构造器:
ClassTest(String sl, String s2) |
此外, select还支持给选中的表达式命名别名,例如:
select p.name as personName from Person as p
|
这种用法与 new map 结合使用更普遍。例如:
select new map(p.name as personName) from Person as p
|
在这种情形下,选择出的是 Map 结构,以 personName 为 key,将实际选出的值作为 value。