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



String hql="from Student"; //检索Student实例的HQL语句



String hql1="select count(*) from Student"; //检索出表中有多少条记录的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<pageCount;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()+"\t"

+stu.getSno()+"\t"

+stu.getSname()+"\t"

+stu.getSsex()+"\t"

+stu.getSage()+"\t"

+stu.getSdept()+"\t"

+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="from Contents where logdate>='"+beginDate+" 00:00:00' and logdate<= '"+endDate+" 00:00:00'";

上述做法存在以下缺陷。

代码的可读性比较差。

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

性能低下。

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

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

String hql="from Student where sname=:name and sage>:age"; //name和age为命名参数

Query query=session.createQuery(hql); //创建查询

query.setParameter("name","李晓梅"); //进行绑定

query.setParameter("age",new Integer(20));

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

对上述代码说明如下。

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

调用Query接口的setParameter()为命名参数赋一固定值。第一个参数指定参数名称,第二个参数指定参数值。当明确知道参数类型时,则可以使用相应的方法,例如参数为int型,可以使用setInteger()方法;参数为String型,可以使用setString()方法。

可以使用按照参数位置对参数进行绑定,如下面的代码所示。

String hql="from Student where sname=? and sage>?"; //声明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中的配置。

<hibernate-mapping>

<class name="hibernate.ch06.Student" table="student" catalog="joblog">

<!--此处省略了配置-->

</class>

<query name="searchStudent"><![CDATA[

from Student s where s.sage>22

]]>

</query>

</hibernate-mapping>

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

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

Query query=session.getNamedQuery("searchStudent"); //用getNamedQuery得到查询

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

Iterator it=list.iterator();



while(it.hasNext()){

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

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

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值