Hibernate中的HQL语言
一、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语言的更多相关文章
- Hibernate中关于HQL查询返回List<Object>数据的结果集问题
---恢复内容开始--- 开发中遇到的一个小问题,使用Hibernate中的HQL查询时,使用query.list()查询出来的是一个List<Object>结果集 原来代码: publi ...
- 分享知识-快乐自己:Hibernate 中的 HQL 语句的实际应用
概要: Hibernate 支持三种查询方式: HQL查询.Criteria查询及原声 SQL (Native SQL)查询. HQL(Hibernate Query Language,Hiberna ...
- Hibernate中的HQL查询与缓存机制
HQL:完全面向对象查询 SQL的执行顺序: 1.From 2.Where 过滤基础数据 where与having的区别:1.顺序不同 2.where过滤基础数据 3. 过滤聚合函数 3.Group ...
- Hibernate 中update hql语句
今天在MySQL中用hibernate测试update语句发现以下问题: update语句竟然不去作用: 表机构如下: create table student(sid int primary key ...
- Hibernate中的HQL的基本常用小例子,单表查询与多表查询
<span style="font-size:24px;color:#3366ff;">本文章实现HQL的以下功能:</span> /** * hql语法: ...
- Hibernate中常用HQL
HQL是Hibernate自带的查询语言 HQL是一种面向对象的查询语言.SQL的操作对象是数据表和列等数据对象,而HQL的操作对象是类.实例.属性等. HQL的语法很像SQL的语法 以下举例均以学生 ...
- hibernate中使用HQL进行数据库查询
1.写的规则比较简单,我讲一下,如图Station这个不是数据库中的表,而是entity包中的类名Station,可以省略 select * 2.返回的类型自动转化为String类型,不用你自己再转化 ...
- Hibernate中的HQL
一.查询所有的时候 List<Company> list=session.createQuery("from Company as c order by c.cid desc&q ...
- Hibernate 中出现 users is not mapped 问题
Hibernate 中出现 users is not mapped 问题: 解答:HQL语句中表名应该是ORM映射的类名,所以应该改成: (如果是用注解生成实体类,那就是注解的那个类)String ...
随机推荐
- J2ME开发基本语法及小实例专题
原文发布时间为:2008-07-31 -- 来源于本人的百度文章 [由搬家工具导入] http://www.wcplym.com/sbjtClassArtl.asp?id=4 ·Canva专题:漂亮的 ...
- 一款基于bootstrap的文件上传插件,现在很多手机webapp都在用
官网:http://plugins.krajee.com/file-input
- Mysql让主键归0
Mysql 相关技术 1.Mysql 让主键 归0: TRUNCATE TABLE * 2.只清空数据表,主键不归0: DELETE FROM 'TABLE' 3.重启数据库: /etc/init.d ...
- LeetCode OJ-- Spiral Matrix
https://oj.leetcode.com/problems/spiral-matrix/ 螺旋矩阵,逆着转,输出矩阵中的元素. 在纸上模仿,然后记左上角(l1,l2)右上角(l1,r2),左下角 ...
- (39)C#Ping类
一.Ping类 引用命名空间 using System.Net.NetworkInformation 控制台版 using System; using System.Collections.Gener ...
- [ONTAK2010]Peaks
题目大意: 一个图上有$n(n\leq100000)$个带权点,$m(m\leq500000)$条带权边.有$q(q\leq500000)$组询问,每次询问从点$v$出发,只经过权值小于等于$x$的边 ...
- debug : 调试主进程启动的子进程
http://blog.csdn.net/lostspeed/article/details/10109867
- javascript --- 原型继承与属性拷贝的综合应用
对于继承来说,主要目标就是将一些现有的功能据为己有.也就是说,我们在新建一个对象的时候,通常首先继承现有对象,然后再为其添加额外的属性和方法. 对此,我们可以通过一个函数调用来完成. 具体而言就是: ...
- android listview 添加数据
<span style="white-space:pre"> </span>listView = (ListView) findViewById(R.id. ...
- 使用TypeDescriptor给类动态添加Attribute【转】
源文 : http://www.cnblogs.com/bicker/p/3326763.html 给类动态添加Attribute一直是我想要解决的问题,从msdn里找了很久,到Stack Overf ...