精通HQL(3)

2019-05-18 20:29

String hql=\ //检索Student实例的HQL语句

String hql1=\//检索出表中有多少条记录的HQL语句

Query q=session.createQuery(hql1); //创建Query

List list=q.list(); //执行查询

int count=((Integer)list.get(0)).intValue();//总的对象个数

int pageCount=(count+pageSize-1)/pageSize; //总的页数

Query query=session.createQuery(hql); //创建检索Student的查询

for(int i=0;i

query.setFirstResult(i*pageSize); query.setMaxResults(pageSize);

List list1=query.list(); //执行查询

Iterator it=list1.iterator();

System.out.println(\ while(it.hasNext()){

Student stu=(Student)it.next(); System.out.println(stu.getId()+\ +stu.getSno()+\ +stu.getSname()+\ +stu.getSsex()+\ +stu.getSage()+\ +stu.getSdept()+\ +stu.getSaddress() ); } } }

pagenate(int pageSize) 函数对指定的对象实例循环查询,每次循环检索出pageSize个对象。

HQL语句select count(*) from Student检索出学生对象的个数,把对象个数存入到变量count中。

用(count+pageSize-1)/pageSize计算出总的页数。 每次for循环时输出一页的记录。 6.2.3 绑定参数

使用绑定参数可以在程序运行时动态决定一些参数的值。下面比较不使用绑定参数和使用绑定参数时的情况。

第4章的4.3.6节中,ViewLog.java中有一个检索指定时间段日志的HQL语句:

String HQL=\Contents where logdate>='\00:00:00' and logdate<= '\上述做法存在以下缺陷。 代码的可读性比较差。

安全性问题,用户可能执行别的代码或存在SQL注入式攻击。 性能低下。

查询语句中以“:”开头的变量叫做命名参数,把命名参数和一个具体的值进行绑定的过程叫做绑定参数。如下面的程序。

//声明hql语句,待绑定的参数以\开头

String hql=\和age为命名参数 Query query=session.createQuery(hql); //创建查询 query.setParameter(\李晓梅\ //进行绑定 query.setParameter(\

List list=query.list(); //执行查询 对上述代码说明如下。

“:name”指定了命名参数name,“:age”指定了命名参数age。

调用Query接口的setParameter()为命名参数赋一固定值。第一个参数指定参数名称,第二个参数指定参数值。当明确知道参数类型时,则可以使用相应的方法,例如参数为int型,可以使用setInteger()方法;参数为String型,可以使用setString()方法。 可以使用按照参数位置对参数进行绑定,如下面的代码所示。

String hql=\//声明hql语句,命名参数用“?”代替

Query query=session.createQuery(hql); //创建查询 query.setParameter(0,\李晓梅\ //绑定参数 query.setParameter(1,new Integer(20));

List list=query.list(); //执行查询 在HQL语句中用问号“?”代替命名参数。此时setParameter()函数的第一个参数指定参数的位置(position),0为HQL查询语句中的第一个参数,1为第二个参数,以此类推。 6.2.4 在映射文件配置HQL语句

为了使程序具有更大的灵活性,Hibernate可以在映射文件中配置HQL语句。如下所示为在Student.hbm.xml中的配置。

22 ]]>

可以用如下代码访问配置文件中的HQL语句。

Session session=HibernateSessionFactory.currentSession();//创建Session

Query query=session.getNamedQuery(\ //用getNamedQuery

得到查询

List list=query.list(); //执行查询 Iterator it=list.iterator();

while(it.hasNext()){

Student stu=(Student)it.next();

System.out.println(stu.getSname()); }

其中,getNamedQuery()函数用来访问映射文件Student.hbm.xml中配置的HQL语句,参数为配置的名称。

6.3 HQL的嵌套子查询 6.3.1 嵌套子查询的概念

在SQL中,一个select-from-where语句成为一个查询块。将一个查询块嵌套在另一个查询块的where子句或having短语的条件中,这样的查询称为嵌套查询或者子查询。如: from Student s where s.sno in

(select sno from sc where cno='1')

上面的HQL语句在Hibernate后台生成的SQL语句为: select

student0_.id as id1_, student0_.Sno as Sno1_,

student0_.Sname as Sname1_, student0_.Ssex as Ssex1_, student0_.Sdept as Sdept1_, student0_.Sage as Sage1_,

student0_.Saddress as Saddress1_ from

joblog.student student0_ where

student0_.Sno in ( select

sc1_.Sno from

joblog.sc sc1_ where

sc1_.Cno='1' )

在这个例子中,下层查询块select sno from sc where cno='1'是嵌套在上层查询块from Student s where s.sno in的where条件中的。上层查询块又称为外层查询或父查询,下层查询块称为内层查询或者子查询。

嵌套查询的求解方法由里向外处理,每一个子查询在其上一级查询处理之前查询,子查询的结果用于建立父查询的查询条件。 6.3.2 带有IN谓词的子查询

带有IN谓词的子查询指的是父查询与子查询用谓词IN连接,判断某个属性列值是否在子

查询的结果中。在嵌套查询中,子查询的结果往往是一个集合。

例如,查询与“李晓梅”在同一个系学习的学生。可以使用如下的方法进行:先查询“李晓梅”所在系,然后查询在这个系里的所有学生。先查询的作为条件是子查询,后查询的是父查询。具体代码如下。 from Student s where s.sdept in

(select s.sdept from s where s.sname='李晓梅') 6.3.3 比较子查询

如果确切知道子查询返回的是单值,可以用=、>、>=、<、<=、<>比较运算符进行比较子查询。

例:查询与“李晓梅”在同一个系学习的学生。

这个例子与上面的例子一样。“李晓梅”只可能在一个系学习,所以子查询返回单值,可以用比较子查询。 from Student s where s.sdept=

(select s.sdept from s where s.sname='李晓梅') 6.3.4 带有ANY或ALL的子查询

使用ANY或者ALL谓词时,必须同时使用比较运算符。查询其他系中比计算机系任一学生年龄小的学生名单。 from Student s

where s.sage'计算机系'

子查询查询出计算机系学生的所有年龄,然后用“?计算机系?是父查询的条件。 带有ANY或ALL的子查询的谓词如下所述。 >ANY,大于子查询结果中的某个值。

>=ANY,大于等于子查询中的某个值。 <=ANY,小于等于子查询中的某个值。 =ANY,等于子查询中的某个值。

!=ANY或者<>ANY,不等于子查询中的某个值。 >ALL,大于子查询中的所有值。

>=ALL,大于等于子查询中的所有值。 <=ALL,小于等于子查询中的所有值。 =ALL,等于子查询中的所有值。

!=ALL或者<>ALL,不等于子查询中的任何一个值。 6.4 HQL的多表查询

对象之间总是有各种各样的关系,关联关系是类之间最常见的关系。多表查询是HQL中的强大功能之一,包括内连接、左连接和右连接等。多表查询的设置及运行都比较麻烦,在运行本节中的示例时,务必保证每一步都没有错误。 6.4.1 表之间的关联关系

在数据库joblog中用到了3个表:student(学生表)、course(课程表)和sc(选课表)。这些表的详细信息见6.1.1节“示例中用到的默认数据库表和数据”。在现实模型中,一个学生

可以选择多门课程,一个课程可以被多个学生选择,student和course是多对多的关联关系。为了便于演示HQL的多表查询,本节中假设student和course之间是单向关联关系。

在多对多的关联关系中,一般来说有个中间表,这个表描述了多对多关系,这就是选课表sc,sc每一行数据代表一个学生的选课和成绩。 各个表的主键、外键设置如下。 student表的主键是id字段。 course表的主键是id字段。 sc表的主键是id字段。

sc表中的Sno字段是student表id字段的外键。 sc表中的Cno字段是course表id字段的外键。 图6-8是3个表之间关系的直观表示。

图6-8 3个表之间的关系

在MySQL Query Browser中设置好上述关系。如果此处设置不正确,可能会影响多表连接查询。其中sc表的建表信息如下(其中包含了外键关系)。 CREATE TABLE 'joblog'. 'sc' (

'id' int(10) unsigned NOT NULL auto_increment COMMENT 'id', 'Sno' int(10) unsigned NOT NULL default '0' COMMENT '学号', 'Cno' int(10) unsigned NOT NULL default '0' COMMENT '课程号', 'Grade' int(10) unsigned default NULL COMMENT '成绩', PRIMARY KEY ('id'), KEY 'FK_sc_1' ('Sno'), KEY 'FK_sc_2' ('Cno'),

CONSTRAINT 'FK_sc_1' FOREIGN KEY ('Sno') REFERENCES 'student' ('id'), /* 外键信息 */

CONSTRAINT 'FK_sc_2' FOREIGN KEY ('Cno') REFERENCES 'course' ('id') /* 外键信息 */

) ENGINE=InnoDB DEFAULT CHARSET=gb2312; 6.4.2 表中的数据

这一节中用到了3个表的数据,student表和course表的数据如6.1节中图6-2和6-4所示,但是sc表的内容变为图6-9所示的数据,其中Sno和Cno存储的分别是student表和course表中对应的主键值。


精通HQL(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:烟囱施工方案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: