Hibernate查询(HQL)

(一)O/R Mapping编程模型

1、映射模型

a、jpa  annotation

b、hibernate  annotation  extension

c、hibernate  xml

d、jpa xml

2、编程接口(在使用编程接口时,要区分好jpa和hibernate)

a、jpa

b、hibernate

3、查询语言

a、Native Sql:本地查询语言,即oracle,mysql自己的查询语言(功能最强大,不利于跨平台)

b、HQl:hibernate的查询语言,将自己写的HQL转化为具体数据库的方言。

c、EJBQL(JPQL):相当于HQL的一个子集。

d、QBC:Query  By Criteria通过Criteria接口来实现查询。(criterion 标准/准则/约束)

e、QBE:Query By  Example


QBC:通过Restrictions添加约束。学习QBC通过了解Restrictions的使用即可。QBE是QBC的一部分。

对于QBE,有约束性:就是对于范围不好表示。

(二)HQL

HQL(Hibernate Query Language) 是面向对象的查询语言, 它和 SQL 查询语言有些相似. 在 Hibernate 提供的各种检索方式中, HQL 是使用最广的一种检索方式. 它有如下功能:

  1. 在查询语句中设定各种查询条件;
  2. 支持投影查询, 即仅检索出对象的部分属性;
  3. 支持分页查询;
  4. 支持连接查询;
  5. 支持分组查询, 允许使用 HAVING 和 GROUP BY 关键字;
  6. 提供内置聚集函数, 如 sum(), min() 和 max();
  7. 支持子查询;
  8. 支持动态绑定参数;
  9. 能够调用 用户定义的 SQL 函数或标准的 SQL 函数。

HQL 查询包括以下步骤:

  1. 获取Hibernate Session对象。
  2. 编写HQL语句
  3. 以HQL语句作为参数,调用Session的createQuery方法创建查询对象。
  4. 如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值。
  5. 调用Query对象的list()或uniqueResult()方法返回查询结果列表(持久化实体集)

Qurey 接口支持方法链编程风格, 它的 setXxx() 方法返回自身实例, 而不是 void 类型,因此可以写类似于.setXxx().setXxx().setXxx()...样式的语句。

HQL实用技术


一:属性查询(SimplePropertyQuery) 
1,单一属性查询 
*返回结果集属性列表,元素类型和实体类中相应的属性一致 
2, 多个属性查询, 
* 返回集合中的元素是object数组, 
* 其中数组元素的类型和对应属性在实体类中的类型一致 
代码: 
for(Iterator iterator=list.iterator();iterator.hasNext();) 

Object[] obj=(Object[])iterator.next(); 
System.out.println("sid:="+obj[0].toString()+"   sname:="+obj[1]); 

3, 通过hql来动态实例化对象 
代码: 
List list=session.createQuery("select new Student(sid,sname) from Student").list(); 

for (Iterator iterator=list.iterator();iterator.hasNext();){ 
Student student=(Student) iterator.next(); 
System.out.println("sid:="+student.getSid()+"   sname:="+student.getSname()); 

4,采用别名查询 
代码: 
//List list=session.createQuery("select s.sid, s.sname from Student as s").list(); 
List list=session.createQuery("select s.sid, s.sname from Student s").list(); 

二:简单对象查询(SimplyObjectQuery) 
1,返回对象集合(可以忽略select) 
代码: 
//List list=session.createQuery("from Student").list(); 
//List list=session.createQuery("from Student as s").list(); 
List list=session.createQuery("from Student s").list(); 
2,采用select查询对象 (必须使用别名)
* 必须要使用别名 
代码: 
//List list=session.createQuery("select s from Student as s").list();   //使用as起别名   也可以省as
List list=session.createQuery("select s from Student s").list(); 
3,查询单一对象的操作 
代码: 
Object obj=session.createQuery("select s from Student s where s.sid=:mysid") 
.setParameter("mysid", 12) 
.uniqueResult(); 
4,分页查询 
* setFirstResult(int firstResult) 
* Set the first row to retrieve. 
* If not set, rows will be retrieved beginnning from row 0. 
* firstResult - a row number, numbered from 0 
代码: 
List list=session.createQuery("select s from Student s") 
   .setFirstResult(5)   //从第几条记录开始
   .setMaxResults(5)  //一页几条记录

   .list(); 
三:简单条件查询(SimpleConditionQuery) 
1,可以拼凑字符串 
代码: 
List stuList=session.createQuery("select s.sid, s.sname from Student as s where s.sname like '%1%'").list(); 
2,注意:可以采用?占位的方式来传递参数 
*参数的索引从0开始 
*传递的参数值不能用单引号号括起来 

参数索引值从0开始,索引位置。通过setString,setParameter设置参数 

*注意方法链编程 
代码: 
/* 
*Query query=ession.createQuery("select s.sid, s.sname from Student as s where s.sname like ?"); 
*query.setParameter(0, "%1%"); 
*List stuList=query.list(); 
*/ 
List stuList=session.createQuery("select s.sid, s.sname from Student as s where s.sname like ?") 
    .setParameter(0, "%1%") 
    .list(); 
3,通过参数名(:参数名)传参的方式进行查询 通过setProperties设置参数 

setParameter()方法包含三个参数,分别是命名参数名称,命名参数实际值,以及命名参数映射类型。对于某些参数类型setParameter()方法可以根据参数值的Java类型,猜测出对应的映射类型,因此这时不需要显示写出映射类型

代码: 
/*Object obj=session.createQuery("select s.sid, s.sname from Student as s where s.sname like :myname and s.sid=:myid") 
    .setParameter("myname", "%1%") 
    .setParameter("myid", 98) 
    .uniqueResult();//.list(); 

Object[] objs=(Object[])obj; 
System.out.println("s.sid:="+objs[0].toString()+"  s.sname:="+objs[1].toString()); 
*/ 
List stuList=session.createQuery("select s.sid, s.sname from Student as s where s.sname like :myname and s.sid=:myid") 
    .setParameter("myname", "%1%") 
    .setParameter("myid", 98) 
    .list(); 
4,传递多个参数的查询 
* 支持in查询,需要setParameterList("myids", new Object[]{12,13,14})的方式进行参数传递
代码: 
List stuList=session.createQuery("select s.sid, s.sname from Student as s where s.id in(:myids)") 
    .setParameterList("myids", new Object[]{12,13,14}) 
    .list(); 
5, 查询2009年2月入学的学员信息 
*支持Sql函数查询 
代码: 
List stuList=session.createQuery("select s.sid, s.sname ,s.schoolDate from Student as s where year(s.schoolDate)=:myyear and month(s.schoolDate)=:mymonth") 
    .setParameter("myyear", 2009) 
    .setParameter("mymonth", 2) 
    .list(); 
6,查询2009-02-10到2009-02-15号入学的学员信息 
*注意:在进行日期查询时 
*setParameter("startDate", formatter.parse("2009-02-10 00:00:00")) 
*方法中第二个参数是一个Object对象(Date类型对象) 
代码: 
SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 

List stuList=session.createQuery("select s.sid, s.sname ,s.schoolDate from Student as s where s.schoolDate between :startDate and :endDate") 
    .setParameter("startDate", formatter.parse("2009-02-10 00:00:00")) 
    .setParameter("endDate", formatter.parse("2009-02-15 23:59:59")) 
    .list(); 
四:原生SQL语句查询(SqlQueryTest_4) 
*这里用的是createSQLQuery().list(); 
代码: 
List stuList=session.createSQLQuery("select * from Student").list(); 
五:外置命名查询(NamedQueryTest_5) 
* 1.在映射文件中采用<query>标签来定义HQL语句,不必限定文件!!!注意:映射文件中的HQL语句不可以出错,否则会导致 QuerySyntaxException,特别是要查询的实体类名写错的情况。(Error in named query: selectAllStudents org.hibernate.hql.ast.QuerySyntaxException: Students is not mapped)。 
* 2.在程序中通过session.getNamedQuery(hql_name)得到查询语句 
代码: 
List list=session.getNamedQuery("selectAllStudents") 
.setParameter("mysid",12).list(); 
六:对象导航查询(ObjectNavQueryTest_6) 
代码: 
List list= session.createQuery("select s.sname from Student as s where s.clsInfo.cname like :myname") 
      .setParameter("myname", "%1%") 
      .list(); 
七:联合查询(JoinQueryTest_7) 
1,联合查询* 内连接查询 
* 获取已经参加班级报名的所有学生名号和其所在班级名称 
代码: 
List list=session.createQuery("select s.sname,c.cname from Student as s join s.clsInfo as c").list(); 
2,联合查询* 左连接查询 
* 获取所有班级名称和其学员姓名 
* 以班级信息表为主表,进行左外连接查询 
代码: 
List list=session.createQuery("select c.cname ,s.sname from ClassInfo as c left join c.studentSet as s").list(); 
3,联合查询 * 右连接查询 
* 获取所有学员姓名和其所属班级名称 
* 以学员信息表为主表,进行右外连接查询 
代码: 
List list=session.createQuery("select s.sname, c.cname  from ClassInfo as c right join c.studentSet as s").list(); 
八:(StateQueryTest_8) 
1,聚合函数使用 
代码: 
//List list=session.createQuery("select count(*) from Student").list(); 
//long count=(Long) list.get(0); 

long count=(Long) session.createQuery("select count(*) from Student").uniqueResult();
2,分组查询 
代码: 
List list=session.createQuery("select c.cname, count(s) from Student as s inner join s.clsInfo as c group by c.cname order by c.cname").list(); 



结论:QL应该和导航关系结合,共同为查询提供服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一位远方的诗人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值