更新对象的HQL语句与SQL语法很相似,使用update更新对象的值。如下面例子更新对象的sage属性。
ransaction tx=null; //声明事务 try{
tx=session.beginTransaction(); //开始事务
String hql=\//更新语句 Query query=session.createQuery(hql);
query.executeUpdate(); //执行
tx.commit(); //成功,则提交 tx=null;
}catch(Exception e){ e.printStackTrace(); if(tx!=null){
tx.rollback(); //失败则回滚 } }finally{
session.close(); }
6.1.9 查询计算属性值
HQL可以查询经过计算的值,在一些需要计算的地方可以进行计算,例如查询全体学生的姓名和出生年份。
select s.sname,2006-s.sage from Student as s
select子句十分灵活,几乎和SQL语句有着同样的能力,对象的属性值可以参与运算。 这行代码假设当前的年份是2006年。 下面是另外几个查询计算属性值的例子。 select s.sname,2006-s.sage from Student as s 6.1.10 使用函数
当需要调用函数时,HQL提供了一些类似SQL的函数。这些函数可以简化操作。例如查询学生的姓名、出生日期和性别,其中性别用小写表示。
select s.sname,2006-s.sage,lower(s.ssex) from Student as sselect s.sname,2006-s. sage from Student as s
6.1.11 between...and...和not between... and...确定查询范围
between...and...用来查询属性值在指定范围内的实体对象,not between...and...用来查询属性值不在指定范围内的实体对象。如查询学生年龄在22到23之间的学生: select s.sno,s.sname,s.sage from Student s where s.sage between 22 and 23 查询将返回如下结果。
--------------------------------------------------------------------- 1 20040001 李晓梅 22 计算机系
--------------------------------------------------------------------- 2 20040002 王蒙 23 外语系
--------------------------------------------------------------------- 4 20050004 李文 22 计算机系
between后跟的是查询范围的下限,and后跟的是查询范围的上限,所以下面的查询语句总
没有对象返回。
from Student s where s.sage between 23 and 22 6.1.12 in和not in确定查询集合
关键字in用来查询指定属性值属于指定集合的对象,关键字not in用来查询指定属性值不属于指定集合的对象。如查询不是计算机系,也不是数学系的学生。
select s.sno,s.sname,s.sdept from Student s where s.sdept not in ('计算机系','数学系') 查询将返回如下结果。
--------------------------------------------------------------------- 20040002 王蒙 外语系
--------------------------------------------------------------------- 20050003 姜浩 化学系
--------------------------------------------------------------------- 20050005 薛鹏 生物系 6.1.13 like进行模糊查询
用like进行模糊查询时有两个可用的通配符:“%”和“_”。“%”代表长度大于等于0的字符,“_”代表长度为1的单个字符。 查询姓李的学生:
select s.sno,s.sname,s.sdept from Student s where s.sname like '%李%' 查询结果如下。
--------------------------------------------------------------------- 20040001 李晓梅 计算机系
--------------------------------------------------------------------- 20050004 李文 计算机系
--------------------------------------------------------------------- 20050006 李思 数学系 查询姓名为两个字符的学生:
select s.sno,s.sname,s.sdept from Student s where s.sname like '__' 查询结果如下。
--------------------------------------------------------------------- 20040002 王蒙 外语系
--------------------------------------------------------------------- 20050003 姜浩 化学系
--------------------------------------------------------------------- 20050004 李文 计算机系
--------------------------------------------------------------------- 20050005 薛鹏 生物系
--------------------------------------------------------------------- 20050006 李思 数学系 6.1.14 and逻辑与
当要检索指定的多个条件,且条件的逻辑关系为与时,使用“and”关键字。如检索计算机系的女生,这个检索要求包含两个条件:“计算机系”和“女生”。
select s.sno,s.sname,s.sdept from Student s where s.sdept='计算机系' and s.ssex='F' 检索的结果如下。
---------------------------------------------------------------------
20040001 李晓梅 计算机系
--------------------------------------------------------------------- 20050004 李文 计算机系 6.1.15 or逻辑或
当检索的多个条件,且条件的逻辑关系为或时,使用“or”关键字。如检索姓王,或者年龄大于22岁的学生:
select s.sno,s.sname,s.sdept from Student s where s.sname like '王%' or s.sage>22 检索结果如下。
--------------------------------------------------------------------- 20040002 王蒙 外语系
--------------------------------------------------------------------- 20050005 薛鹏 生物系 6.1.16 order by对结果进行排序
“order by”关键字对结果进行排序,默认为升序。“order by asc”为升序,“order by desc”为降序。例如将学生表中的学生按照年龄升序排序: from Student s order by s.sage 检索结果如下。
--------------------------------------------------------------------- 6 20050006 李思 20 数学系
--------------------------------------------------------------------- 3 20050003 姜浩 21 化学系
--------------------------------------------------------------------- 1 20040001 李晓梅 22 计算机系 --------------------------------------------------------------------- 4 20050004 李文 22 计算机系
--------------------------------------------------------------------- 2 20040002 王蒙 23 外语系
--------------------------------------------------------------------- 5 20050005 薛鹏 24 生物系
将学生表中的学生按照年龄降序排列,按照所在系升序排列。 from Student s order by s.sage,s.sdept desc 6.1.17 group by对记录进行分组
对查询进行分组可以对查询进行细化。分组经常和聚集函数一起使用,这样聚集函数将作用于每个分组。
group by的用法为:
select 属性1,属性2,属性3 ,…,属性n from 类名 group by 属性m 其中属性1,属性2,…,属性n必须满足下列条件。
要么作为聚集函数的参数,要么为属性m。例如,检索各个系的学生的平均年龄: select avg(s.sage),s.sdept from Student s group by s.sdept 其中字段s.sage作为平均值函数的参数,s.sdept是group by后的一个属性。检索的结果如下。 --------------------------------------------------------------------- 化学系 21.0
--------------------------------------------------------------------- 计算机系 22.0
--------------------------------------------------------------------- 生物系 24.0
--------------------------------------------------------------------- 数学系 20.0
--------------------------------------------------------------------- 外语系 23.0
检索各个课程号与对应的选课人数。
select cno,count(sno) from SC s group by s.cno 6.1.18 having关键字
having关键字和group by关键字搭配使用,它对分组后的记录进行筛选,输出符合having指定条件的组。例如查询人数超过1000人的系。
select s.sdept from Student s group by s.sdept having count(*)>1000 查询男生人数多于500人的系。
select s.sdept from Student s where s.ssex=?M? group by s.sdept having count(*)>500 以上面查询男生人数多于500人的系为例:
select s.sdept from Student s where s.ssex=?M? group by s.sdept having count(*)>500 查询过程中同时使用group by和having关键字时,查询步骤如下。 (1)检索符合s.ssex=?M?的所有男生。 (2)根据s.sdept分组成不同的系。
(3)对于每一个分组,计算分组中的记录条数大于500的系。 (4)将符合上述条件的s.sdept选出来。
where和having的区别在于作用对象不同。where作用于基本表,而having作用于分组后的组。
6.1.19 聚集函数
聚集函数包括count()、avg()、sum()、max()、min(),其含义如表6-1所示。 表6-1 聚集函数及其含义 聚 集 函 数 count() avg() sum() max() min() 含 义 计算符合条件的记录条数 计算符合条件的平均值 计算符合条件的和 计算符合条件的最大值 计算符合条件的最小值 各个函数的用法举例如下。 检索学生实例的对象个数: select count(*) from Student 检索计算机系的人数:
select count(*) from Student s where s.sdept='计算机系' 检索学生实例的平均年龄: select avg(s.sage) from Student s
检索课程表course的所有课程的学分的总和: select sum(c.ccredit) from Course c
检索课程号为“1”的课程的最高成绩: select max(s.grade) from SC s where s.cno=1 检索课程号为“1”的课程的最低成绩:
select min(s.grade) from SC s where s.cno=1
聚集函数经常和group by分组关键字搭配使用。 检索各门课程的平均成绩:
select s.cno,avg(s.grade) from SC s group by s.cno 检索各科不及格人数:
select s.cno,count(*) from SC s where s.grade<60 group by s.cno 6.2 HQL进阶
下面讲述HQL一些比较高级的应用,包括如何使用HQL查询继承关系数据、绑定参数和在配置文件中使用查询语句。
6.2.1 查询类及其所有继承的类的实例
默认情况下,当查询一个类时,Hibernate会自动搜索这个类的所有继承类。假如有如下3个类,类的关系如图6-7所示。
图6-7 Animal类及其子类Bird和Mammal
当调用如下HQL语句时,会查询出所有的Animal实例、Bird实例和Mammal实例。 from Animal
所有的类均继承自java.lang.Object,所以下面的HQL语句查询所有的类的对象实体,即查询所有映射表的记录。 from java.lang.Object
6.2.2 限制每次查询的返回对象数
Query接口提供了两个函数,用于限制每次查询返回的对象数。
SetFirstResult(int firstResult) 用于设置从哪一个对象开始检索。参数firstResult设置开始检索的起始记录。
setMaxResults(int maxResults) 用于设置每次检索返回的最大对象数。参数maxResults用于设置每次检索返回的对象数目。
这两个函数结合起来用,经常用于分页显示对象。例如数据库中有10000条记录,如果一次性显示实在太多,就可以进行分页显示。
下面的程序当每次循环时,从Student实例中检索出pageSize个对象,并输出到控制台,是一个典型的分页显示程序。 /**
* 分页输出对象
* @param pageSize 每页显示的记录条数 */
public void pagenate(int pageSize) {
Session session=HibernateSessionFactory.currentSession(); //创建Session