一、HQL语言简介

HQL全称是Hibernate Query Language,它提供了是十分强大的功能,它是针对持久化对象,直接取得对象,而不进行update,delete和insert等操作。而且HQL是面向对象的,具备继承,多态和关联等特性。

HQL的语法类似于SQL,其常用的方法如下:

[select|update|delete 子句] [from 类名列表] [where 子句] [group by 子句] [order by 子句]

[select|update|delete 子句]用于查询,更新和删除。

[from 类名列表]指定查询的持久化类所在的的数据表名。

[where 子句]给出查询的条件。

[group by 子句]用于对数据进行分组。

[order by 子句]对查询结果进行排序。



注意:除了Java类与属性的名称外,HQL查询语句对大小写并不敏感。 所以 SeLeCT 与 sELEct 以及 SELECT 是相同的,但是 org.hibernate.eg.FOO 并不等价于 org.hibernate.eg.Foo 并且 foo.barSet 也不等价于 foo.BARSET。 





二、HQL语法详解

-----[select|update|delete]--------

select关键词后跟的是需要返回的对象或者对象属性,且属性必须属于from子句中给出的类列表。使用select可以直接存入一个List对象或直接封装为一个对象。

使用示例:

1、查询具体属性

select stu.cores.english from Student as stu;

上述语句查询出学生的英语成绩

2、查询并放入List对象

select new List(stu.id,stu.name) from Student as stu;

查询了学生的学号和名字,放入一个List中

3、查询并生成对象

select new Student(stu.id,stu.name) from Student as stu;

查询了学生的学号和名字,并生成一个Student对象。使用前提:Student类中存在相应的构造方法。

4、查询所有属性

from Student

多数情况下,我们可以为查询的实体对象指定一个别名,方便在其他地方引用。

from Student as stu



update和delete是Hibernate3新加入的特性。这样我们更新数据库就有两种方式。

1、先修改持久化对象的值,之后提交事务更新数据。

2、使用HQL语句实现。不过不推荐这种方式。





---------from子句-----------

from子句是最简单的HQL,例如from Student,也可以写成 select s from Student s。它简单的返回Student类的所有实例。





---------where子句----------

HQL也支持子查询,它通过where子句实现这一机制。where子句可以让用户缩小要返回的实例的列表范围。例如下面语句会返回所有名字为"kang"的Student实例:

Query query = session.createQuery("from Student as stu where stu.name='kang'");

1、where子句允许出现的表达式

数学操作:+,-,*,/

真假比较操作:=, >=, <=, <>, !=, like

逻辑操作:and ,or, not

字符串连接:||

SQL标题函数 :如upper()和lower()

2、如果查询返回多条记录,可以用以下关键字来量化

all:表示所有的记录。

any:表示所有记录中的任意一条。

some:与any相同。

in:与any等价。

exists:表示子查询至少要返回一条记录。

查询示例:

返回所有学生年龄都大于18的班级对象

from Group g where 18<all  (select s.age from g.students s)

返回在所有学生中有一个学生的年龄等于22的班级:

from Group g where 22 = any (select s.age from g.students s)

或者

from Group g where 22= some(select s.age from g.students s)

或者

from Group g where 22 in (select s.age from g.students s)

 



-----------Group by子句--------------

在HQL语句中同样支持使用group by子句分组查询,还支持group by子句结合聚集函数的分组统计查询,大部分标准的SQL聚集函数都可以在HQL语句中使用,比如:

count(),sum(),max(),min(),avg()等。(前提是数据库支持having语句,例如mysql不支持)

count():统计记录条数。

min():求最小值。

max():求最大值。

sum():求和。

avg():求平均值。

例如,要取得Student实例的数量,可以编写如下HQL语句:

select count(*) from Student

取得Student平均年龄的HQL语句:

select avg(s.age) from Student as s

可以使用distinct去除重复的数据:

select distinct s.age from Student as s

如下面的程序代码:

String hql=”select count(user),user.age from User user group by user.age having count(user)>10 ”;//mysql不行

List list=session.createQuery(hql).list();







--------------order by子句------------

查询返回列表可以按照任何返回的类或者组件的属性排序,asc为正序排列(从小到大),desc为降序排列(从大到小)

按照学生的学号正序排列

from Studen as stu order by stu.id asc







---------------联合查询--------------

与SQL一样,HQL也支持连接查询,如内连接,外连接和交叉连接:

inner join:内连接

left outer join:左外连接

rigth outer join:右外连接

full join:全连接,但不常用

下面重点介绍下内连接查询,左外连接和或右外连接和内连接大同小异,而全连接几乎没有使用得到的地方。

inner join可以简写为join,例如在查询得到的Group对象时,内连接取得对应的Student对象,实现的程序代码如下:

Student stu = null;
Group group = null;
Query query = session.createQuery("from Group g join g.students");
List list = query.list();
Object obj[] = null;
for(int i = 0 ; i < list.size(); i++)
{
obj = (Object[])list.get(i);
group = (Group)obj[0];//group是数组是第一个对象
stu = (Student)obj[1];//stu是数组的第二个对象
System.out.println(stu.getName()+"属于"+group.getName());
}

---------------子查询---------------

对于支持子查询的数据库,Hibernate支持在查询中使用子查询。一个子查询必须被圆括号包围起来(经常是SQL聚集函数的圆括号)。 甚至相互关联的子查询(引用到外部查询中的别名的子查询)也是允许的。 

from Cat as fatcat where fatcat.weight > (select avg(cat.weight) from DomesticCat cat)







---------------参数绑定--------------

Hibernate中对动态查询参数绑定提供了丰富的支持,那么什么是查询参数动态绑定呢?其实如果我们熟悉传统JDBC编程的话,我们就不难理解查询参数动态绑定,

如下代码传统JDBC的参数绑定:

PrepareStatement pre=connection.prepare(“select * from User where user.name=?”);

pre.setString(1,”xiaokang”);

ResultSet rs=pre.executeQuery();

在Hibernate中也提供了类似这种的查询参数绑定功能,而且在Hibernate中对这个功能还提供了比传统JDBC操作丰富的多的特性,在Hibernate中共存在4种参数绑

定的方式,下面我们将分别介绍:

1、按参数名称绑定:

 在HQL语句中定义命名参数要用”:参数名”的形式,形式如下:

 Query query=session.createQuery(“from User user where user.name=:customername and user.customerage=:age ”);

 query.setString(“customername”,name);

 query.setInteger(“customerage”,age);

上面代码中用:customername和:customerage分别定义了命名参数customername和customerage,然后用Query接口的setXXX()方法设定名参数值,setXXX()方法包

含两个参数,分别是命名参数名称和命名参数实际值。





2、按参数位置邦定:

在HQL查询语句中用”?”来定义参数位置,形式如下:

Query query=session.createQuery(“from User user where user.name=? and user.age =? ”);

query.setString(0,name);

query.setInteger(1,age);

同样使用setXXX()方法设定绑定参数,只不过这时setXXX()方法的第一个参数代表邦定参数在HQL语句中出现的位置编号(由0开始编号),第二个参数仍然代表参数实际值。

注:在实际开发中,提倡使用按名称邦定命名参数,因为这不但可以提供非常好的程序可读性,而且也提高了程序的易维护性,因为当查询参数的位置发生改变时,按名称邦定名参数的方式中是不需要调整程序代码的。





3、setParameter()方法:

在Hibernate的HQL查询中可以通过setParameter()方法邦定任意类型的参数,如下代码:

 String hql=”from User user where user.name=:customername ”;

 Query query=session.createQuery(hql);

 query.setParameter(“customername”,name,Hibernate.STRING);

如上面代码所示,setParameter()方法包含三个参数,分别是命名参数名称,命名参数实际值,以及命名参数映射类型。对于某些参数类型setParameter()方法可以更具参数值的Java类型,猜测出对应的映射类型,因此这时不需要显示写出映射类型,像上面的例子,可以直接这样写:

query.setParameter(“customername”,name);但是对于一些类型就必须写明映射类型,比如java.util.Date类型,因为它会对应Hibernate的多种映射类型,比如

Hibernate.DATA或者Hibernate.TIMESTAMP。





4、setProperties()方法:

在Hibernate中可以使用setProperties()方法,将命名参数与一个对象的属性值绑定在一起,如下程序代码:

Customer customer=new Customer();
customer.setName(“pansl”);
customer.setAge(80);
Query query=session.createQuery(“from Customer c where c.name=:name and c.age=:age ”);
query.setProperties(customer);

setProperties()方法会自动将customer对象实例的属性值匹配到命名参数上,但是要求命名参数名称必须要与实体对象相应的属性同名。

这里还有一个特殊的setEntity()方法,它会把命名参数与一个持久化对象相关联,如下面代码所示:

Customer customer=(Customer)session.load(Customer.class,”1”);
Query query=session.createQuery(“from Order order where order.customer=:customer ”);
query. setProperties(“customer”,customer);
List list=query.list();

上面的代码会生成类似如下的SQL语句:

Select * from order where customer_ID=’1’;







三、如何使用HQL语句

HQL查询依赖于Query类,每个Query实例对应一个查询对象,使用HQL查询按如下步骤进行:

1.获取Hibernate Session对象

2.编写HQL语句

3.以HQL语句作为参数,调用Session的createQuery方法创建查询对象

4.如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值

5.调用Query独享的list()或uniqueResult()方法返回查询结果列表

例如:

Session s = null;
try{
s = HibernateUtil.getSession();//获取session,前提HibernateUtil中有一个静态方法getSession
String hql = "from Test as test where test.name=?";
Query query = s.createQuery(hql);//创建Query对象
query.setString(0,name);//设置参数
List list = query.list();//查询结果
for(Test test:list){//遍历
System.out.println(test.getName());
}
}finally{
//finally表示数据库一定要被关闭
if(s!=null)
s.close();
}
}
}

Hibernate中的HQL语言的更多相关文章

  1. Hibernate中关于HQL查询返回List<Object>数据的结果集问题

    ---恢复内容开始--- 开发中遇到的一个小问题,使用Hibernate中的HQL查询时,使用query.list()查询出来的是一个List<Object>结果集 原来代码: publi ...

  2. 分享知识-快乐自己:Hibernate 中的 HQL 语句的实际应用

    概要: Hibernate 支持三种查询方式: HQL查询.Criteria查询及原声 SQL (Native SQL)查询. HQL(Hibernate Query Language,Hiberna ...

  3. Hibernate中的HQL查询与缓存机制

    HQL:完全面向对象查询 SQL的执行顺序: 1.From 2.Where 过滤基础数据 where与having的区别:1.顺序不同 2.where过滤基础数据 3. 过滤聚合函数 3.Group ...

  4. Hibernate 中update hql语句

    今天在MySQL中用hibernate测试update语句发现以下问题: update语句竟然不去作用: 表机构如下: create table student(sid int primary key ...

  5. Hibernate中的HQL的基本常用小例子,单表查询与多表查询

    <span style="font-size:24px;color:#3366ff;">本文章实现HQL的以下功能:</span> /** * hql语法: ...

  6. Hibernate中常用HQL

    HQL是Hibernate自带的查询语言 HQL是一种面向对象的查询语言.SQL的操作对象是数据表和列等数据对象,而HQL的操作对象是类.实例.属性等. HQL的语法很像SQL的语法 以下举例均以学生 ...

  7. hibernate中使用HQL进行数据库查询

    1.写的规则比较简单,我讲一下,如图Station这个不是数据库中的表,而是entity包中的类名Station,可以省略 select * 2.返回的类型自动转化为String类型,不用你自己再转化 ...

  8. Hibernate中的HQL

    一.查询所有的时候 List<Company> list=session.createQuery("from Company as c order by c.cid desc&q ...

  9. Hibernate 中出现 users is not mapped 问题

    Hibernate 中出现 users is not mapped 问题: 解答:HQL语句中表名应该是ORM映射的类名,所以应该改成:  (如果是用注解生成实体类,那就是注解的那个类)String ...

随机推荐

  1. Nginx配置https双向认证

    1.      前期的准备工作: 安装openssl和nginx的https模块 cd ~/ mkdir ssl cd ssl mkdir demoCA cd demoCA mkdir newcert ...

  2. js-jquery 中$.ajax -浅显接触

    工作了将近2年,终于开始自己写ajax了!!!真紧张的! 当年培训时就没有学ajax,就让我们自己看看,我是那种主动学习的人吗?不是!!!所以搞不懂ajax!!!!! 在工作中,数据的绑定我们之前都是 ...

  3. RSA 公钥加密算法

    RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的. 这个算法的名字也是他们三个人名字首字母,RSA算法基于一个十分简单的数 ...

  4. Codeforces Gym 100203I I WIN 最大流

    原题链接:http://codeforces.com/gym/100203/attachments/download/1702/statements.pdf 题解 首先寻找每个I,然后枚举形状,如果匹 ...

  5. CODECHEF Nov. Challenge 2014 Chef & Churu

    @(XSY)[分塊] Hint: 題目原文是英文的, 寫得很難看, 因此翻譯為中文. Input Format First Line is the size of the array i.e. \(N ...

  6. Codeforces Round #295 (Div. 1) C. Pluses everywhere

    昨天ZZD大神邀请我做一道题,说这题很有趣啊. 哇,然后我被虐了. Orz ZZD 题目大意: 你有一个长度为n的'0-9'串,你要在其中加入k个'+'号,每种方案就会形成一个算式,算式算出来的值记做 ...

  7. 什么叫PV,UV,PR值

    1.PV PV(page view),即页面浏览量:用户每1次对网站中的每个网页访问均被记录1次.用户对同一页面的多次访问,访问量累计. 2.什么是UV uv(unique visitor),指访问某 ...

  8. 基于GPU加速的三维空间分析【转】

    基于GPU加速的三维空间分析 标签:supermap地理信息系统gisit 文:李凯 随着三维GIS 的快速发展和应用普及,三维空间分析技术以其应用中的实用性成为当前GIS技术研究的热点领域.面对日益 ...

  9. C# 线程中更新ListView某单元格导致闪烁问题的解决

    项目中需要用线程处理一些事务.处理结果(已经处理的比例)随时显示在ListView的某区域. 由于线程循环动作较快,导致被更新的单元格甚至所在行都有闪烁现象. 后来考虑到线程算的值整数部分未必变化很快 ...

  10. sparkSQL1.1入门之十:总结

    回想一下,在前面几章中,就sparkSQL1.1.0基本概念.执行架构.基本操作和有用工具做了基本介绍. 基本概念: SchemaRDD Rule Tree LogicPlan Parser Anal ...