Hibernate的查询语言之HQL(一)——快速入门

摘要:
Hibernate提供了一个非常强大的查询系统。Hibernate有多种查询方法可供选择:Hibernate HQL查询、条件查询,甚至本机SQL查询。此外,Hibernate还提供了一个数据过滤功能,用于过滤目标数据。Hibernate是Hibernate查询语言的缩写。HQL的语法与SQL非常相似,但HQL是一种面向对象的查询语言。HQL查询依赖于query类,每个query实例对应于一个查询对象。使用HQL查询如下:获取Hibernate Session对象。使用HQL语句作为参数,调用Session的createQuery方法来创建查询对象。

  Hibernate提供异常强大的查询体系,使用Hibernat有多种查询方式可以选择:即可以使用Hibernate的HQL查询,也可以使用条件查询,甚至可以使用原生的SQL查询语句。不仅如此, Hibernate还提供了一种数据过滤功能,这些都用于筛选目标数据。

  Hibernate是 Hibernate Query 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()或uniqueResult()方法返回查询结果列表(持久化实体集)。

    下面是一个用例:

    Person和MyEvent两个类的代码及映射文件:

 1 import java.util.HashSet;
 2 import java.util.Set;
 3 
 4 public class Person {
 5     // 定义标识属性
 6     private Integer id;
 7     // 定义Person实例的name属性
 8     private String name;
 9     // 定义Person实例的age属性
10     private Integer age;
11     // 定义Person和MyEvent之间的关联关系
12     private Set<MyEvent> myEvents = new HashSet<MyEvent>();
13     // 定义一个集合属性
14     private Set<String> emails = new HashSet<String>();
15 
16     // 无参数的构造器
17     public Person() {
18     }
19 
20     // 初始化全部属性的构造器
21     public Person(Integer id, String name, Integer age) {
22         this.id = id;
23         this.name = name;
24         this.age = age;
25     }
26 
27     // id属性的setter和getter方法
28     public void setId(Integer id) {
29         this.id = id;
30     }
31 
32     public Integer getId() {
33         return this.id;
34     }
35 
36     // name属性的setter和getter方法
37     public void setName(String name) {
38         this.name = name;
39     }
40 
41     public String getName() {
42         return this.name;
43     }
44 
45     // age属性的setter和getter方法
46     public void setAge(int age) {
47         this.age = age;
48     }
49 
50     public Integer getAge() {
51         return this.age;
52     }
53 
54     // myEvents属性的setter和getter方法
55     public void setMyEvents(Set<MyEvent> myEvents) {
56         this.myEvents = myEvents;
57     }
58 
59     public Set<MyEvent> getMyEvents() {
60         return this.myEvents;
61     }
62 
63     // emails属性的setter和getter方法
64     public void setEmails(Set<String> emails) {
65         this.emails = emails;
66     }
67 
68     public Set<String> getEmails() {
69         return this.emails;
70     }
 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping package="com.example.hql.pojo">
 6     <class name="Person" table="person">
 7         <id name="id" column="person_id">
 8             <generator class="native" />
 9         </id>
10         <property name="name" />
11         <property name="age" />
12         <!-- 映射和MyEvent实体的关联关系 -->
13         <set name="myEvents" table="person_event">
14             <!-- 映射连接表中参照此表主键的外键列的列名 -->
15             <key column="person_id" />
16             <many-to-many class="MyEvent" column="event_id" />
17         </set>
18         <!-- 映射集合属性 -->
19         <set name="emails" table="person_email">
20             <!-- 映射集合属性表中的外键列 -->
21             <key column="person_id" />
22             <!-- 映射集合元素,集合元素是字符串 -->
23             <element type="string" column="email" />
24         </set>
25     </class>
26 </hibernate-mapping>
 1 import java.util.Date;
 2 import java.util.HashSet;
 3 import java.util.Set;
 4 
 5 public class MyEvent {
 6     // 定义标识属性
 7     private Integer id;
 8     // 定义MyEvent对象的名称
 9     private String title;
10     // 定义MyEvent对象的发生时间
11     private Date happenDate;
12     // 定义MyEvent对象和Person对象的关联
13     private Set<Person> actors = new HashSet<Person>();
14 
15     // 无参数的构造器
16     public MyEvent() {
17     }
18 
19     // 初始化全部属性的构造器
20     public MyEvent(Integer id, String title, Date happenDate) {
21         this.id = id;
22         this.title = title;
23         this.happenDate = happenDate;
24     }
25 
26     // id属性的setter和getter方法
27     public void setId(Integer id) {
28         this.id = id;
29     }
30 
31     public Integer getId() {
32         return this.id;
33     }
34 
35     // title属性的setter和getter方法
36     public void setTitle(String title) {
37         this.title = title;
38     }
39 
40     public String getTitle() {
41         return this.title;
42     }
43 
44     // happenDate属性的setter和getter方法
45     public void setHappenDate(Date happenDate) {
46         this.happenDate = happenDate;
47     }
 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping package="com.example.hql.pojo">
 6     <class name="MyEvent" table="event">
 7         <id name="id" column="event_id">
 8             <generator class="native" />
 9         </id>
10         <property name="title" />
11         <property name="happenDate" type="date" />
12         <set name="actors" table="person_event">
13             <key column="event_id" />
14             <many-to-many class="Person" column="person_id" />
15         </set>
16     </class>
17 </hibernate-mapping>

下面是查询代码

 1 import java.text.SimpleDateFormat;
 2 import java.util.Arrays;
 3 import java.util.Date;
 4 import java.util.Iterator;
 5 import java.util.List;
 6 
 7 import org.hibernate.Session;
 8 import org.hibernate.Transaction;
 9 import org.junit.Test;
10 
11 import com.example.hql.pojo.Person;
12 import com.example.util.HibernateSessionFactory;
13 
14 @SuppressWarnings("unchecked")
15 public class HqlQuery {
16     @Test
17     public void findPerson() {
18         // 开启Session
19         Session session = HibernateSessionFactory.getSession();
20         // 开始事务
21         Transaction tx = session.beginTransaction();
22         // 以HQL语句创建Query对象
23         // 执行setString方法为HQL语句的参数赋值
24 
25         List<Person> persons = (List<Person>) session
26                 .createQuery(
27                         "select distinct p from Person p join p.myEvents where title = :eventTitle")
28                 .setString("eventTitle", "很普通的事情").list();
29         // 遍历查询结果
30         for (Iterator<Person> pit = persons.iterator(); pit.hasNext();) {
31             Person p = pit.next();
32             System.out.println(p.getName());
33         }
34         tx.commit();
35         session.close();
36     }
37 
38     @Test
39     public void findPersonByHappenDate() throws Exception {
40         Session session = HibernateSessionFactory.getSession();
41         Transaction tx = session.beginTransaction();
42         // 解析出Date对象
43         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD");
44         Date start = sdf.parse("2012-10-10");
45         System.out.println("系统开始通过日期查找人:" + start);
46         List<Person> persons = session
47                 .createQuery(
48                         "select distinct p from Person p inner join p.myEvents event where event.happenDate between :firstDate and :endDate")
49                 .setDate("firstDate", start).setDate("endDate", new Date())
50                 .list();
51         // 遍历查询结果
52         for (Person p : persons) {
53             System.out.println(p);
54         }
55         tx.commit();
56         session.close();
57     }
58     
59     @Test
60     public void findPersonProperty(){
61         Session session = HibernateSessionFactory.getSession();
62         Transaction tx = session.beginTransaction();
63         List<Object[]> datas = session.createQuery("select distinct p.id, p.name, p.age from Person p join p.myEvents").list();
64         for(Object[] data:datas){
65             System.out.println(Arrays.toString(data));
66         }
67         tx.commit();
68         session.close();
69     }
70 }

  由上面HQL语句可以看出,执行HQL语句类似于用PreparedStatement执行SQL语句,因此HQL语句中可以使用占位符作为参数。HQL的占位符即可使用问号(?),这与SQL语句中的占位符完全一样;也可以使用有名字的占位符,使用有名字的占位符时,应该在占位符名字前增加冒号(:),如上HQL所示。

  编写完HQL语句之后,就可使用Session的createQuery(hql)方法创建Query,Query对象使用setXxx()方法为HQL语句的参数赋值。Query的所有setXxx()方法都有两个版本,分别用于根据参数索引赋值和根据参数名字赋值。

  Query对象可以连续多次围HQL参数赋值,这得益于Hibernate Query的设计。通常的setXxx()方法返回值都是void,单Hibernate Query的setXxx()方法返回值是Query本身,采用了 链式 设计的思想。因此,程序通过Session创建Query后,直接多次调用setXxx()方法为HQL语句的参数赋值。

  Query最后调用list()方法返回查询到的全部结果。

  Query还包含如下两个方法。

  》setFirstResult(int firstResult):设置返回结果从第几条记录开始。

  》setMaxResult(int maxResults):  设置本次查询返回的结果数目。

  这两个方法用于HQL查询实现分页控制。

  HQL语句本身是不区分大小写的。也就是说HQL语句的关键字,函数都不是区别大小写的。但HQL语句中所使用的包名,类名,实例名,属性名都区分大小写。

免责声明:文章转载自《Hibernate的查询语言之HQL(一)——快速入门》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇软件工程迭代开发第五篇Flex :直接显示ToolTip和errorTip(不需要将鼠标移到组件上)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

#应用openxml读写excel代码

这个例子比较简单,没有考虑格式之类的问题。 using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System; using System.Collections.Generic; using System.IO; using Syst...

移动APP 微信支付完整过程(wxPay 方案一)

前两天开始做移动端APP的微信支付,过程中遇到了一些问题,比如支付的过程中返回值总是:-1 {status:false},这些问题已经得到了解决。前人栽树,后人尽管乘凉,那么分享一下整个支付过程(wxPay 方案一): 1、申请微信开发平台的账号、创建移动应用、申请开发者资质认证(整个过程APICLOUD官方网站已经给出了相当明确的操作步骤,与实际操作没有...

JDK的第三个LTS版本JDK17来了

目录 简介 JDK17中的新特性 语言上的新特性 核心库的优化 支持新的平台 预览特性 其他改动 总结 简介 2021年9月JDK17发布了,JDK17是最新的一个LTS版本。所谓LTS版本就是可以得到至少八年产品支持的版本。从2014年的JDK8,到2018年的JDK11,再到2021年的JDK17。 同时Oracle也调整了LTS版本...

NeatUpload 的使用

1 <httpModules> 2 <add name="UploadHttpModule" type="Brettle.Web.NeatUpload.UploadHttpModule, Brettle.Web.NeatUpload" /> 3 </httpModules> 来自 <http://www....

C# 调用Java的WebService的3种方式

C# 调用WebService的3种方式 :直接调用、根据wsdl生成webservice的.cs文件及生成dll调用、动态调用 关于soapheader调用,可以参考 C#调用Java的WebService添加SOAPHeader验证1.问题描述 调用的Java的webservice string Invoke(string func, string r...

Gson的入门使用

Java对象和Json之间的互转,一般用的比较多的两个类库是Jackson和Gson,下面记录一下Gson的学习使用。 基础概念:  Serialization:序列化,使Java对象到Json字符串的过程。  Deserialization:反序列化,字符串转换成Java对象   使用Maven管理Gson,pom.xml导入gson的依赖 <...