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 ...
随机推荐
- linux —— 学习笔记(软件操作:安装、卸载、执行)
目录: 0.相关基本命令 1.安装软件 2.卸载软件 3.打开软件 0.相关基本命令 与软件操作相关的主要命令有:dpkg 和 apt-get . dpkg : “dpkg ...
- adb logcat命令查看并过滤android输出log
cmd命令行中使用adb logcat命令查看android系统和应用的log,dos窗口按ctrl+c中断输出log记录. logcat日志中的优先级/tag标记: android输出的每一条日志都 ...
- Demo_玩家移动(主要注意动画的设置)
using UnityEngine; using System.Collections; public class NewPlayerMove : MonoBehaviour { private fl ...
- Haskell 差点儿无痛苦上手指南
趁着自己重装Linux 虚拟机的机会,把安装 haskell 的过程记录一下,顺便帮那些还犹豫徘徊在haskell门外的读者入门. 基本概念: Haskell : 是一门通用函数式语言,差点儿能够进行 ...
- 合肥三洋股份,惠而浦家电携四大品牌-Take ,所有的市场
大家都知道,数家电企业的日子并不好过.一方面,产品同质化竞争越发激烈.家电市场已进入了恶性价格战时代.还有一方面,消费者对家电产品的需求越发多元化.个性化.这意味着无法满足消费者需求的产品非常 ...
- android studio c++ 自动补全
这两天弄起来了Android ndk,可这东西的配置实在是个问题.对于Eclipse可以通过makefile进行编译,也比较成熟.但是对Android studio来说就蛋疼了,官方是想通过gradl ...
- [转] C++指针加整数、两个指针相减的问题
http://blog.csdn.net/onlyou930/article/details/6725051 说来惭愧,写C++有一段时间了.这个问题从来没有认真考虑过,此次标记于此: 考虑如下问题: ...
- Ubuntu常见问题
1. Ubuntu16.04安装完国际版QQ后发现用不了搜狗输入法 sudo mv /usr/bin/ibus-daemon /usr/bin/ibus-daemon.bak
- RHEL7下PXE+NFS+Kickstart无人值守安装操作系统
RHEL7下PXE+NFS+Kickstart无人值守安装操作系统 1.配置yum源 vim /etc/yum.repos.d/development.repo [development] name= ...
- 向量旋转 UPC 2217
这道题目是13山东省省赛的签到题,题目大意是给等边三角形的两个定点,让求逆时针旋转之后的第三个点的坐标,原来不会向量的旋转,在网上找了找,找到一篇挺好的,直接贴过来. 向量的旋转 实际做题中我们可能会 ...