zoukankan      html  css  js  c++  java
  • Hibernate的查询语言之HQL(一)——快速入门

      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语句中所使用的包名,类名,实例名,属性名都区分大小写。

  • 相关阅读:
    Mac_Homebrew
    Python的路径引用
    OpenTSDB-Writing Data
    OpenTSDB介绍
    Git文件状态描述
    TCollector
    TEXT和BLOB区别
    MySQL索引与Index Condition Pushdown
    webService入门学习(一)
    redis学习笔记(一 基本操作)。
  • 原文地址:https://www.cnblogs.com/ArtsCrafts/p/Hibernate_HQL1.html
Copyright © 2011-2022 走看看