本章介绍了Hibernate的几种主要检索方式:HQL检索方式、QBC检索方式、SQL检索方式。HQL是Hibernate Query Language的缩写,是官方推荐的查询语言。QBC是Query By Criteria的缩写,是Hibernate提供的一个查询接口。Hibernate是一个轻量级的框架,它允许使用原始SQL语句查询数据库。
6.1 HQL基础
HQL是Hiberante官方推荐的Hibernate检索方式,它使用类似SQL的查询语言,以面向对象的方式从数据库中查询。可以使用HQL查询具有继承、多态和关联关系的数据。在检索数据时应优先考虑使用HQL方式。
6.1.1 默认数据库表和数据
在讲解本章时,在没有特殊说明时,用到的数据库均为joblog,也就是在第4章建立的数据库。joblog中添加了3个表:学生表student、课程表course和选课表sc。
学生表student中各字段的结构如图6-1所示,字段的中文含义在Comment列中。
图6-1 学生表的数据结构
学生表student中的数据如图6-2所示,没有特殊说明时,用到的均为这6条记录。
此处仍然使用在第4章建立的HibernateProject项目,但是这里新建了一个包hibernate.ch06,这个包存放本章中的所有代码。在hibernate.ch06包中建立学生表对应的持久化类Student.java,代码如下。
图6-2 学生表中的数据
package hibernate.ch06;
//学生类
public class Student {
private Integer id; //对象标识符
private Integer sno; //学号
private String sname; //姓名
private String ssex; //性别
private String sdept; //所在系别
private Integer sage; //年龄
private String saddress; //籍贯
…… //省略了所有的get/set访问器
}
课程表course中的各个字段的结构如图6-3所示,字段的中文含义在Comment列中。
图6-3 课程表的结构
课程表中的数据如图6-4所示,如果没有特殊说明,用到的均为这4条记录。
图6-4 课程表的数据
在hibernate.ch06中新建持久化类Course.java类,代码如下。
package hibernate.ch06;
//课程类
public class Course {
private Integer id; //对象标识符
private Integer cno; //课程号
private String cname; //课程名
private Integer Ccredit; //学分
…… //省略了get/set访问器
}
选修表sc(sc为student-course的缩写)的结构如图6-5所示,字段的中文含义在Comment列中。
图6-5 选修表的结构
选修表中的数据如图6-6所示,没有特殊说明时,用到的均为这5条记录。
图6-6 选修表的数据
在hibernate.ch06中新建持久化类SC.java,SC.java的代码如下。
package hibernate.ch06;
//选课类
public class SC implements java.io.Serializable {
private Integer id; //id
private Integer sno; //学号
private Integer cno; //课程号
private Integer grade; //成绩
public SC() {
}
…… //省略get/set访问器
}
后面的章节中将用这3个表和3个持久化类进行讲解。
6.1.2 检索类的所有对象
使用HQL语句可以检索出一个类的所有对象,如HQL语句“from Student”表示检索Student类的所有对象。下面的程序检索学生类的所有对象。
Query query=session.createQuery("from Student"); //创建Query对象
List list=query.list(); //执行查询
//以下代码做显示用,以后不再写出来
Iterator it=list.iterator();
while(it.hasNext()){
Student stu=(Student)it.next();
System.out.println("id"+stu.getId());
System.out.println("name"+stu.getSname());
System.out.println("\n");
}
session.createQuery()以HQL查询语句为参数,生成一个查询对象。本例中的HQL语句为“from Student”,这是from子句,格式如下。
from 类名
其中,类名可以为类的全限定名,如:
from hibernate.ch06.Student
Hibernate使用自动引入功能(auto import),会自动寻找需要的类,所以不推荐使用类的全限定名。注意,类名区分大小写,如果写成from student,将会抛出以下异常。
java.lang.NoClassDefFoundError: hibernate/ch06/student (wrong name: hibernate/ch06/Student)
HQL关键字不区分大小写,FROM、from和From是一样的。
调用query.list()时,真正开始执行HQL查询语句,并把查询的结果放在List中。
本例中查询的是Student类中的所有属性,如果查询Student类中的某一个或某几个属性,如查询所有学生的姓名和所在系,需要用到属性查询。
6.1.3 检索类的某几个属性
与SQL语句类似,HQL语句可以检索类的某一个或者某几个属性。以下代码查询所有学生的姓名和所在系。
//创建Query对象
Query query=session.createQuery("select Student.sname,Student.sdept from Student");
List list=query.list(); //执行查询
//以下代码显示查询的信息
Iterator it=list.iterator();
while(it.hasNext()){
Object[] stu=(Object[])it.next();
System.out.println("id"+stu[0]);
System.out.println("name"+stu[1]);
System.out.println("\n");
}
属性查询使用select关键字,属性查询的格式如下。
select 属性1,属性2,… from 类名
属性前可以加上类名加以限定,如:
select 属性1,属性2,… from 类名
但一般没有必要。
属性查询区分大小写,上面的代码中如果写成:
select SNAME,Sdept from Student
将抛出异常,提示找不到属性SNAME和属性Sdept。
查询结果将只显示查询的属性列。
属性查询的结果,对于用it.next()获得的每条记录,可以存储在Object[]数组中,以便进行存取。
6.1.4 指定别名
在查询时,可以用关键字as指定查询的别名,指定别名可以简化查询,有时必需指定别名才能进行查询。以下代码查询学号中含有4的学生的姓名和所在系。
select s.sname,s.sdept from Student as s where s.sno like '%4%'from Student s
s就是类Student的别名。注意as可以省略,即下面的查询语句和上面的语句是等效的。
select s.sname,s.sdept from Student s where s.sno like '%4%'from Student s
6.1.5 where条件子句
where条件子句跟SQL中的where条件子句类似,它检索符合条件的对象。例如,查询所有所在系别为计算机系的学生:
select s.sname,s.sdept from Student s where s.dept=’计算机’
where子句指定查询的条件,其语法和SQL类似。
在where子句中可以指定比较运算符:>、>=、<、<=、<>,其含义分别为大于、大于等于、小于、小于等于、不等于。
查询年龄在22到23岁的学生:
from Student s where s.sage>=22 and s.sage<=23
在where子句中指定查询的属性是否为null:is null、is not null,其含义分别表示为空和不为空。
查询所在籍贯为空的学生:
from Student s where s.saddress is null
6.1.6 使用distinct过滤掉重复值
使用distinct关键字将去掉结果中的重复值,只检索符合条件的对象。如下面的例子检索学生实例中的不重复的年龄。
Session session=HibernateSessionFactory.currentSession(); //创建Session
String hql="select distinct s.sage from Student s"; //HQL查询语句
Query query=session.createQuery(hql); //创建查询
List list=query.list(); //执行查询
检索的结果如下,可见结果中去掉了一个重复的22岁。
20
21
22
23
24
6.1.7 删除对象
HQL语句可以直接对复合条件的对象进行删除,可以指定删除的对象,并在提交后永久持久化到数据库。HQL使用delete进行删除,如删除年龄大于25岁的学生可以使用如下代码。
Session session=HibernateSessionFactory.currentSession(); //创建Session
Transaction tx=null; //声明事务
try{
tx=session.beginTransaction(); //开始事务
//创建查询
String hql="delete Student s where s.sage>25";
Query query=session.createQuery(hql);
query.executeUpdate(); //执行
tx.commit(); //成功,则提交
tx=null;
}catch(Exception e){
e.printStackTrace();
if(tx!=null){
tx.rollback(); //失败则回滚
}
}finally{
session.close();
}
注意以下两点。
在删除对象时,执行query.executeUpdate()进行数据删除,但只有执行了tx.commit()进行事务提交时,才真正从数据库中删除数据。
如果设置了级联删除,则与之相关联的对象实例也被删除。
6.1.8 更新对象值
更新对象的HQL语句与SQL语法很相似,使用update更新对象的值。如下面例子更新对象的sage属性。
ransaction tx=null; //声明事务
try{
tx=session.beginTransaction(); //开始事务
String hql="update Student s set s.sage='22' where s.id=11"; //更新语句
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.1 HQL基础
HQL是Hiberante官方推荐的Hibernate检索方式,它使用类似SQL的查询语言,以面向对象的方式从数据库中查询。可以使用HQL查询具有继承、多态和关联关系的数据。在检索数据时应优先考虑使用HQL方式。
6.1.1 默认数据库表和数据
在讲解本章时,在没有特殊说明时,用到的数据库均为joblog,也就是在第4章建立的数据库。joblog中添加了3个表:学生表student、课程表course和选课表sc。
学生表student中各字段的结构如图6-1所示,字段的中文含义在Comment列中。
图6-1 学生表的数据结构
学生表student中的数据如图6-2所示,没有特殊说明时,用到的均为这6条记录。
此处仍然使用在第4章建立的HibernateProject项目,但是这里新建了一个包hibernate.ch06,这个包存放本章中的所有代码。在hibernate.ch06包中建立学生表对应的持久化类Student.java,代码如下。
图6-2 学生表中的数据
package hibernate.ch06;
//学生类
public class Student {
private Integer id; //对象标识符
private Integer sno; //学号
private String sname; //姓名
private String ssex; //性别
private String sdept; //所在系别
private Integer sage; //年龄
private String saddress; //籍贯
…… //省略了所有的get/set访问器
}
课程表course中的各个字段的结构如图6-3所示,字段的中文含义在Comment列中。
图6-3 课程表的结构
课程表中的数据如图6-4所示,如果没有特殊说明,用到的均为这4条记录。
图6-4 课程表的数据
在hibernate.ch06中新建持久化类Course.java类,代码如下。
package hibernate.ch06;
//课程类
public class Course {
private Integer id; //对象标识符
private Integer cno; //课程号
private String cname; //课程名
private Integer Ccredit; //学分
…… //省略了get/set访问器
}
选修表sc(sc为student-course的缩写)的结构如图6-5所示,字段的中文含义在Comment列中。
图6-5 选修表的结构
选修表中的数据如图6-6所示,没有特殊说明时,用到的均为这5条记录。
图6-6 选修表的数据
在hibernate.ch06中新建持久化类SC.java,SC.java的代码如下。
package hibernate.ch06;
//选课类
public class SC implements java.io.Serializable {
private Integer id; //id
private Integer sno; //学号
private Integer cno; //课程号
private Integer grade; //成绩
public SC() {
}
…… //省略get/set访问器
}
后面的章节中将用这3个表和3个持久化类进行讲解。
6.1.2 检索类的所有对象
使用HQL语句可以检索出一个类的所有对象,如HQL语句“from Student”表示检索Student类的所有对象。下面的程序检索学生类的所有对象。
Query query=session.createQuery("from Student"); //创建Query对象
List list=query.list(); //执行查询
//以下代码做显示用,以后不再写出来
Iterator it=list.iterator();
while(it.hasNext()){
Student stu=(Student)it.next();
System.out.println("id"+stu.getId());
System.out.println("name"+stu.getSname());
System.out.println("\n");
}
session.createQuery()以HQL查询语句为参数,生成一个查询对象。本例中的HQL语句为“from Student”,这是from子句,格式如下。
from 类名
其中,类名可以为类的全限定名,如:
from hibernate.ch06.Student
Hibernate使用自动引入功能(auto import),会自动寻找需要的类,所以不推荐使用类的全限定名。注意,类名区分大小写,如果写成from student,将会抛出以下异常。
java.lang.NoClassDefFoundError: hibernate/ch06/student (wrong name: hibernate/ch06/Student)
HQL关键字不区分大小写,FROM、from和From是一样的。
调用query.list()时,真正开始执行HQL查询语句,并把查询的结果放在List中。
本例中查询的是Student类中的所有属性,如果查询Student类中的某一个或某几个属性,如查询所有学生的姓名和所在系,需要用到属性查询。
6.1.3 检索类的某几个属性
与SQL语句类似,HQL语句可以检索类的某一个或者某几个属性。以下代码查询所有学生的姓名和所在系。
//创建Query对象
Query query=session.createQuery("select Student.sname,Student.sdept from Student");
List list=query.list(); //执行查询
//以下代码显示查询的信息
Iterator it=list.iterator();
while(it.hasNext()){
Object[] stu=(Object[])it.next();
System.out.println("id"+stu[0]);
System.out.println("name"+stu[1]);
System.out.println("\n");
}
属性查询使用select关键字,属性查询的格式如下。
select 属性1,属性2,… from 类名
属性前可以加上类名加以限定,如:
select 属性1,属性2,… from 类名
但一般没有必要。
属性查询区分大小写,上面的代码中如果写成:
select SNAME,Sdept from Student
将抛出异常,提示找不到属性SNAME和属性Sdept。
查询结果将只显示查询的属性列。
属性查询的结果,对于用it.next()获得的每条记录,可以存储在Object[]数组中,以便进行存取。
6.1.4 指定别名
在查询时,可以用关键字as指定查询的别名,指定别名可以简化查询,有时必需指定别名才能进行查询。以下代码查询学号中含有4的学生的姓名和所在系。
select s.sname,s.sdept from Student as s where s.sno like '%4%'from Student s
s就是类Student的别名。注意as可以省略,即下面的查询语句和上面的语句是等效的。
select s.sname,s.sdept from Student s where s.sno like '%4%'from Student s
6.1.5 where条件子句
where条件子句跟SQL中的where条件子句类似,它检索符合条件的对象。例如,查询所有所在系别为计算机系的学生:
select s.sname,s.sdept from Student s where s.dept=’计算机’
where子句指定查询的条件,其语法和SQL类似。
在where子句中可以指定比较运算符:>、>=、<、<=、<>,其含义分别为大于、大于等于、小于、小于等于、不等于。
查询年龄在22到23岁的学生:
from Student s where s.sage>=22 and s.sage<=23
在where子句中指定查询的属性是否为null:is null、is not null,其含义分别表示为空和不为空。
查询所在籍贯为空的学生:
from Student s where s.saddress is null
6.1.6 使用distinct过滤掉重复值
使用distinct关键字将去掉结果中的重复值,只检索符合条件的对象。如下面的例子检索学生实例中的不重复的年龄。
Session session=HibernateSessionFactory.currentSession(); //创建Session
String hql="select distinct s.sage from Student s"; //HQL查询语句
Query query=session.createQuery(hql); //创建查询
List list=query.list(); //执行查询
检索的结果如下,可见结果中去掉了一个重复的22岁。
20
21
22
23
24
6.1.7 删除对象
HQL语句可以直接对复合条件的对象进行删除,可以指定删除的对象,并在提交后永久持久化到数据库。HQL使用delete进行删除,如删除年龄大于25岁的学生可以使用如下代码。
Session session=HibernateSessionFactory.currentSession(); //创建Session
Transaction tx=null; //声明事务
try{
tx=session.beginTransaction(); //开始事务
//创建查询
String hql="delete Student s where s.sage>25";
Query query=session.createQuery(hql);
query.executeUpdate(); //执行
tx.commit(); //成功,则提交
tx=null;
}catch(Exception e){
e.printStackTrace();
if(tx!=null){
tx.rollback(); //失败则回滚
}
}finally{
session.close();
}
注意以下两点。
在删除对象时,执行query.executeUpdate()进行数据删除,但只有执行了tx.commit()进行事务提交时,才真正从数据库中删除数据。
如果设置了级联删除,则与之相关联的对象实例也被删除。
6.1.8 更新对象值
更新对象的HQL语句与SQL语法很相似,使用update更新对象的值。如下面例子更新对象的sage属性。
ransaction tx=null; //声明事务
try{
tx=session.beginTransaction(); //开始事务
String hql="update Student s set s.sage='22' where s.id=11"; //更新语句
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
相关推荐
Hibernate HQL基础练习小列子+数据库
**HQL查询语言基础** HQL(Hibernate Query Language)是Hibernate框架中用于操作对象关系映射(ORM)的查询语言,它与SQL类似,但专为面向对象编程设计。HQL允许开发者以类和对象的方式编写查询,而不是直接处理...
本教程将深入讲解HQL的基础语句,包括ID生成策略、集合参数传递以及不同的传参方式。 ### 1. ID生成策略 在Hibernate中,实体类的主键(ID)生成策略是关键部分,它决定了如何为新记录分配唯一标识。以下是几种...
HQL的基础包括了各种查询条件的设定,这些条件使得我们可以精确地定位和检索所需的数据。下面将详细介绍HQL中的一些关键操作和子句: 1. **Where 子句**: Where 子句是HQL中用于限制查询结果的关键部分,它接受一...
【HQL基础】 HQL,全称Hibernate Query Language,是Hibernate框架提供的面向对象的查询语言,它类似于SQL,但更专注于对象模型而非数据库表结构。HQL是Hibernate官方推荐的检索数据的主要方式,因为它能够更好地...
在学习HQL基础时,我们通常会用到一些示例数据。在这个例子中,我们有三个数据库表:`student`(学生表)、`course`(课程表)和`sc`(选课表)。`student`表包含学生的学号(`sno`)、姓名(`sname`)、性别(`ssex...
2. **HQL基础《上》.docx** 和 **HQL基础《下》.docx**:这两份文档可能详细讲解了HQL的基础语法,包括查询基本操作、条件表达式、排序和分组等。 3. **HQL进阶.docx**:这份文档可能涉及更高级的主题,如联接查询...
#### HQL基础 HQL是一种面向对象的查询语言,它支持基本的SQL操作,并在此基础上进行了封装,使其更加符合面向对象的编程风格。HQL查询通常是在Session对象上调用`createQuery()`或`createSQLQuery()`方法来执行的...
1. HQL基础语法:了解如何写基本的查询语句,如SELECT、FROM、WHERE等。 2. 关联查询:理解如何在HQL中处理实体间的关联,如JOIN操作。 3. 子查询:可能需要在查询中嵌套查询,以满足特定的条件。 4. 分页和排序:...
Hibernate Query Language(HQL)是...通过学习和实践这些HQL基础知识,你将能够更高效地利用Hibernate进行数据操作。为了深入了解,可以参考`Hibernate+HQL.chm`文档,它可能包含了更详细的概念解释和示例代码。
#### 二、HQL 基础 HQL 是一种面向对象的查询语言,它支持 SQL 的大部分功能,并提供了一些面向对象的特性。HQL 查询通常用于检索特定条件下的对象集合或单个对象。 ##### 1. HQL 语法特点: - **面向对象**:HQL ...
HQL 查询语言基础知识 HQL(Hibernate Query Language)是一种面向对象的查询语言,用于在 Hibernate 框架中查询数据库。HQL 查询语言基础知识是 Hibernate 中的基础组件之一,对于开发人员来说,掌握 HQL 查询语言...
一、HQL基础 1. **语法规则**:HQL语法与SQL有许多相似之处,如查询、选择、排序等,但主要的区别在于HQL以类和属性为操作对象,而SQL以表和字段为主。例如,`from Employee as e`相当于SQL中的`select * from ...
#### 三、HQL 基础查询 - **基本的 SELECT 语句**: ```sql SELECT cat FROM com.example.Cat AS cat; ``` 这里 `Cat` 是一个 Java 类,代表数据库中的表。`AS cat` 可以省略,如果省略,则默认别名为类名...
#### 二、HQL基础 ##### 2.1 默认数据库表和数据 在本节中,我们将使用一个示例数据库`joblog`,该数据库包含三个表:学生表`student`、课程表`course`以及选课表`sc`。这些表的结构和数据将作为学习HQL的基础。 ...
1. HQL基础:HQL基于面向对象的概念,将表映射为类,列映射为属性,使得查询更符合Java开发者的思维模式。它支持连接(inner/outer/full joins)、投影、聚合、分组、排序、子查询以及SQL函数调用。 2. 简单HQL示例...
**一、HQL基础** 1. **查询语句结构**:HQL查询语句的基本结构类似于SQL,由`FROM`、`WHERE`、`SELECT`、`GROUP BY`、`ORDER BY`等关键字组成,但使用类名和属性而非表名和列名。 2. **实体与类**:在HQL中,...
1. **HQL基础概念** HQL是Hibernate提供的面向对象的查询语言,与SQL类似,但更加面向对象,减少了数据库方言的差异,提高了代码的可移植性。HQL支持对持久化类及其属性的查询,能够直接操作对象,而无需关心底层的...
### HQL基础 1. **基本查询语句**: HQL的基本查询结构与SQL类似,包括`SELECT`, `FROM`, `WHERE`子句。例如,查询所有`User`对象: ```java Query query = session.createQuery("from User"); ``` 2. **属性...
#### 二、HQL基础示例 以题目中的部分代码为例,假设存在以下几张表:`student`、`team`、`course`和`student_course`。这些表之间的关系如下: - `student`表包含五个字段:`id`、`name`、`cardId`、`age`和`team...