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两个类的代码及映射文件:
import java.util.HashSet;
import java.util.Set; public class Person {
// 定义标识属性
private Integer id;
// 定义Person实例的name属性
private String name;
// 定义Person实例的age属性
private Integer age;
// 定义Person和MyEvent之间的关联关系
private Set<MyEvent> myEvents = new HashSet<MyEvent>();
// 定义一个集合属性
private Set<String> emails = new HashSet<String>(); // 无参数的构造器
public Person() {
} // 初始化全部属性的构造器
public Person(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
} // id属性的setter和getter方法
public void setId(Integer id) {
this.id = id;
} public Integer getId() {
return this.id;
} // name属性的setter和getter方法
public void setName(String name) {
this.name = name;
} public String getName() {
return this.name;
} // age属性的setter和getter方法
public void setAge(int age) {
this.age = age;
} public Integer getAge() {
return this.age;
} // myEvents属性的setter和getter方法
public void setMyEvents(Set<MyEvent> myEvents) {
this.myEvents = myEvents;
} public Set<MyEvent> getMyEvents() {
return this.myEvents;
} // emails属性的setter和getter方法
public void setEmails(Set<String> emails) {
this.emails = emails;
} public Set<String> getEmails() {
return this.emails;
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example.hql.pojo">
<class name="Person" table="person">
<id name="id" column="person_id">
<generator class="native" />
</id>
<property name="name" />
<property name="age" />
<!-- 映射和MyEvent实体的关联关系 -->
<set name="myEvents" table="person_event">
<!-- 映射连接表中参照此表主键的外键列的列名 -->
<key column="person_id" />
<many-to-many class="MyEvent" column="event_id" />
</set>
<!-- 映射集合属性 -->
<set name="emails" table="person_email">
<!-- 映射集合属性表中的外键列 -->
<key column="person_id" />
<!-- 映射集合元素,集合元素是字符串 -->
<element type="string" column="email" />
</set>
</class>
</hibernate-mapping>
import java.util.Date;
import java.util.HashSet;
import java.util.Set; public class MyEvent {
// 定义标识属性
private Integer id;
// 定义MyEvent对象的名称
private String title;
// 定义MyEvent对象的发生时间
private Date happenDate;
// 定义MyEvent对象和Person对象的关联
private Set<Person> actors = new HashSet<Person>(); // 无参数的构造器
public MyEvent() {
} // 初始化全部属性的构造器
public MyEvent(Integer id, String title, Date happenDate) {
this.id = id;
this.title = title;
this.happenDate = happenDate;
} // id属性的setter和getter方法
public void setId(Integer id) {
this.id = id;
} public Integer getId() {
return this.id;
} // title属性的setter和getter方法
public void setTitle(String title) {
this.title = title;
} public String getTitle() {
return this.title;
} // happenDate属性的setter和getter方法
public void setHappenDate(Date happenDate) {
this.happenDate = happenDate;
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example.hql.pojo">
<class name="MyEvent" table="event">
<id name="id" column="event_id">
<generator class="native" />
</id>
<property name="title" />
<property name="happenDate" type="date" />
<set name="actors" table="person_event">
<key column="event_id" />
<many-to-many class="Person" column="person_id" />
</set>
</class>
</hibernate-mapping>
下面是查询代码
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List; import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import com.example.hql.pojo.Person;
import com.example.util.HibernateSessionFactory; @SuppressWarnings("unchecked")
public class HqlQuery {
@Test
public void findPerson() {
// 开启Session
Session session = HibernateSessionFactory.getSession();
// 开始事务
Transaction tx = session.beginTransaction();
// 以HQL语句创建Query对象
// 执行setString方法为HQL语句的参数赋值 List<Person> persons = (List<Person>) session
.createQuery(
"select distinct p from Person p join p.myEvents where title = :eventTitle")
.setString("eventTitle", "很普通的事情").list();
// 遍历查询结果
for (Iterator<Person> pit = persons.iterator(); pit.hasNext();) {
Person p = pit.next();
System.out.println(p.getName());
}
tx.commit();
session.close();
} @Test
public void findPersonByHappenDate() throws Exception {
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
// 解析出Date对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD");
Date start = sdf.parse("2012-10-10");
System.out.println("系统开始通过日期查找人:" + start);
List<Person> persons = session
.createQuery(
"select distinct p from Person p inner join p.myEvents event where event.happenDate between :firstDate and :endDate")
.setDate("firstDate", start).setDate("endDate", new Date())
.list();
// 遍历查询结果
for (Person p : persons) {
System.out.println(p);
}
tx.commit();
session.close();
} @Test
public void findPersonProperty(){
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
List<Object[]> datas = session.createQuery("select distinct p.id, p.name, p.age from Person p join p.myEvents").list();
for(Object[] data:datas){
System.out.println(Arrays.toString(data));
}
tx.commit();
session.close();
}
}
由上面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(一)——快速入门的更多相关文章
- Hibernate的查询语言之HQL(二)——Hibernate查询的from字句
from 是最简单的HQL语句,也是最基本的HQL语句.from 关键字后紧跟持久化类的类名.例如: from Person 表明从Person持久化类中取出全部的实例. 大部分时候,推荐位该Pers ...
- (转)Hibernate快速入门
http://blog.csdn.net/yerenyuan_pku/article/details/64209343 Hibernate框架介绍 什么是Hibernate 我们可以从度娘上摘抄这样有 ...
- Hibernate入门第一讲——Hibernate框架的快速入门
Hibernate框架的概述 什么是框架? 框架指的是软件的半成品,已经完成了部分功能. JavaEE开发的三层架构 了解框架的基本概念之后,我们就来看看Hibernate框架处于JavaEE开发的经 ...
- Hibernate知识点小结(一)--快速入门
一.Hibernate的简介 1.Hibernate是一个开放源代码的对象关系映射框架 2.对象关系映射:ORM Object Relation Mapping 对象与数据 ...
- Hibernate第一篇【介绍Hibernate,简述ORM,快速入门】
前言 前面已经学过了Struts2框架了,紧接着就是学习Hibernate框架了-本博文主要讲解介绍Hibernate框架,ORM的概念和Hibernate入门 什么是Hibernate框架? Hib ...
- Hadoop生态圈-Hive快速入门篇之HQL的基础语法
Hadoop生态圈-Hive快速入门篇之HQL的基础语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客的重点是介绍Hive中常见的数据类型,DDL数据定义,DML数据操作 ...
- Hibernate查询语言(HQL)
Hibernate查询语言(HQL)与SQL(结构化查询语言)相同,但不依赖于数据库表. 我们在HQL中使用类名,而不是表名. 所以是数据库独立的查询语言. HQL的优点 HQL有很多优点. 它们如下 ...
- 笔记44 Hibernate快速入门(一)
一.Hibernate简介 Hibernate 是传统 Java 对象和数据库服务器之间的桥梁,用来处理基于 O/R 映射机制和模式的那些对象. Hibernate 架构是分层的,作为数据访问层,你不 ...
- 【简明翻译】Hibernate 5.4 Getting Started Guide 官方入门文档
前言 最近的精力主要集中在Hibernate上,在意识到Hibernate 5 的中文资料并不多的时候,我不得不把目光转向Hibernate的官方doc,学习之余简要翻一下入门文档. 原文地址:htt ...
随机推荐
- 每一个web开发者都应该了解的HTTP/2
我认为每一个 web 开发者都应该对这个支撑了整个 Web 世界的 HTTP 协议有所了解,这样才能帮助你更好的完成开发任务.在这篇文章中,我将讨论什么是 HTTP,它是怎么产生的,它的地位,以及我们 ...
- Ueditor 1.4.3 jsp utf-8版图片上传问题
- java 服务端解决ajax跨域问题
//过滤器方式 可以更改为拦截器方式public class SimpleCORSFilter implements Filter { public void doFilter(ServletRequ ...
- 基于 Quartz 开发企业级任务调度应用--转
Quartz 基本概念及原理 Quartz Scheduler 开源框架 Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现.该项目于 2009 ...
- 洛谷 1373 小a和uim之大逃离
/* 很容易想到f[i][j][k][l][01] 表示到ij点 两个人得分为kl 01表示这一步谁走的 因为起点不同 路径不同 所以要枚举起点.. 时间复杂度 O(nmk*nmk) 空间复杂度 O( ...
- codevs1051单词接龙(栈)
/* 看到n的范围就觉得这个不可能是DP啥的 因为这个接龙的规则十分的简单 只要前缀相同即可 所以先按字典序排一遍 这样保证符合规则的一定挨着 然后弄一个stack 每次拿栈顶元素看看待入栈的元素是否 ...
- gvim & vim
安装了 GVim for Windows. 一 普通功能配置 配置文件 _vimrc 在安装目录下面. 关闭闪屏和声音提示功能: set visualbell t_vb= "关闭visual ...
- Django runserver show client ip
get path of basehttp.py $ python >>> import site >>> site.getsitepackages() ['/usr ...
- 安装Fedora(附镜像下载地址)
近期又试着装了一遍Fedora,强迫症迫使我写一些简单的教程,方便以后有用 先把VM配置好,然后进入Fedora 点击Skip 这几按照提示一步一步来 选个人桌面 手工分区 分区的时候注意下每个区的容 ...
- 织梦(dedecms)如何清空全部文章和删除后新增文章id号归1的方法
很多朋友在使用织梦程序做网站的过程中,难免需要添加一些测试文章用于测试网站功能模板等,还有些人朋友网站改版需要变更内容的时候,面对着众多的老文章后总是一筹莫展! 由于织梦后台并不自带一键删除整站文章的 ...