您的位置:首页 > 数据库

Hibernate(二)HQL&SQL参数绑定、投影和分页以及命名查询

2014-12-20 14:18 639 查看
在上文中讲解了HQL查询和sql查询的一些基本技能,本篇将对HQL查询和原生sql查询的知识进行一些补充。

一、参数绑定

无论是HQL查询还是SQL查询还是讲要讲到的命名查询,都支持两种参数绑定形式——按位置、按名称绑定(以下均以hql查询为例)

1.按照位置绑定参数

此时在HQL语句中使用“?”占位符来定义参数位置,如:

Query query=session.createQuery("from Dept where deptno=?");
传递的时候以setXXX()的形式来传递,参数位置从0开始:

//参数是什么类型的就调用set类型的方法
query.setInteger(0,20);
//...省略
2.按照命名绑定参数

此时在HQL语句中使用“:参数名字”(英文冒号+名字)的形式定义参数,如:

Query query=session.createQuery("from Dept where deptno=:deptNo");
传递的时候还是以setXXX()的形式传递,此时就不是按位置了:

query.setInteger("deptNo",20);
//...省略
3.绑定各种类型的参数

①使用通用的方式绑定参数:


当不知道参数的类型是何种类型的时候,使用setParameter()方法进行绑定:

Query query=session.createQuery("from Dept where deptno=?");
query.setParameter(0,20);
②绑定命名参数和一个对象的属性值

如果查询中包含多个对象的时候,为了方便可能会将查询条件封装成一个类,此时再绑定参数就有了简便的方法

使用命名参数+setProperties()方法进行绑定,如:

class DeptCondition{
private int selectNo;
private String selectName;
//省略get、set
}
测试类:

DeptCondition d=new DeptCondition();
d.setSelectName("sal");
d.setSelectNo(20);
Query query=session.createQuery("from Dept where deptName=:selectName and deptNo=:selectNo");
query.setProperties(d);
List<Dept> list=query.list();
注意:命名参数的名字一定要和对象的属性名字一致

二、投影和分页

1.投影

在上文中简单提了下select子句。有时候可能不需要查询对象的全部属性,此时就可以使用select 子句来选取某些属性进行查询,获取的查询结果可以分为三种形式

①将结果封装成Object对象

Query query=session.createQuery("select deptName from Dept");
List<String> list=query.list();
for (String string : list) {
System.out.println(string);
}
②将结果封装成Object数组

这个前面已经接触过了

Query query=session.createQuery("select empNo,empName from Emp");
List<Object[]> list=query.list();
for (Object[] item : list) {
System.out.println(item[0]+"\t"+item[1]);
}
③将结果封装成新的对象

比如我这里查询empNo和empName,我可以新写一个类EmpExt(或者现有的),主要是要求如下带参构造和无参构造
Query query=session.createQuery("select new EmpExt(empNo,empName) from Emp");
List<EmpExt> list=query.list();
2.分页

分页在以前是个很头痛的问题,如果查询条件多了的话实现起来会相当复杂。Hibernate提供了简单的分页方法

Query接口的setFirstResult(arg0)用于设置第一条记录的位置setMaxResults(arg0)用于设置查询的最大记录条数

int pageIndex=1;
int pageSize=2;
Query query=session.createQuery("from Emp");
query.setFirstResult((pageIndex-1)*pageSize);
query.setMaxResults(pageSize);
//...
另外,Query还有一个uniqueResult()方法,此方法用于获取唯一结果,如果查询的记录中的条数不唯一的时候,

调用此方法会抛出异常


三、命名查询

命名查询就是在映射文件中定义好查询语句,然后在程序中调用即可,HQL查询和SQL查询都支持

1.HQL查询中的命名查询


Emp.hbm.xml映射文件中的配置如下:

<hibernate-mapping package="com.wzj.entity">
<class name="Emp" table="MYEMP">
<!--省略-->
</class>
<!--
query元素和class元素是一个级别的
另外,加<![CDATA[语句]]>的作用:
如果查询语句中含有where子句并且有“<”和“>”的时候,会对标签进行
转义,通过此方式声明了里面的语句只是以字符串的形式存在
-->
<query name="getEmpByNo">
<![CDATA[from Emp where empNo=:no]]>
</query>
</hibernate-mapping>
测试类:

//使用getNamedQuery方法查询
Query query=session.getNamedQuery("getEmpByNo");
query.setInteger("no", 7788);
Emp e=(Emp)query.uniqueResult();
System.out.println(e.getEmpName());
2.原生sql中的命名查询

sql查询的命名查询同样是跟class是同一个级别的,使用sql-query元素
<sql-query name="getEmpByNo">
<!--
注意此处使用return元素
alias:别名
class:将要封装成此属性值对应的对象
-->
<return alias="e" class="com.wzj.entity.Emp"></return>
<!-- 原生sql语句 -->
<![CDATA[select * from EMP  where e.empno=:no]]>
</sql-query>
注意,return元素的作用:

现在通过getNamedQuery()方法进行查询,无论是HQL还是sql查询,返回的都是Query接口的对象,不会再出现SQLQuery对象

如果使用原生sql查询,结果则是上文讲的Object[]类型的,如果此时想使用SQLQuery特有的方法将查询结果封装成

对应的对象,但是没有SQLQuery对象是调用不出来的;所以return元素的作用就很明显了,就是将结果封装成对应的对象

alias表示查询的别名


以上三点呢就是本篇对上文的补充,后续将介绍Criteria查询
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: