Hibernate-HQL基础

基本概述

Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Language)查询提供了更加丰富的和灵活的查询特性,因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,HQL查询在涵盖Criteria查询的所有功能的前提下,提供了类似标准SQL语句的查询方式,同时也提供了更加面向对象的封装。

HQL详解

这里以学生选课系统的表为例,讲解HQL。现提供三张表的SQL语句以及映射图。

--建立学生表
create table student
(sid number primary key , --学号sname varchar2(45) not null, --学生姓名ssex  char(2) not null,--性别sdept varchar2(10) not null, --所在系sage  number(3) ,--年龄saddress varchar2(45) --住址
);--学生表中的数据
insert into student values(20040001,'林青霞','F','计算机系',22,'上海');
insert into student values(20040002,'刘德华','M','外语系',23,'南京');
insert into student values(20050003,'成龙','M','化学系',21,'山东');
insert into student values(20050004,'林可欣','F','计算机系',22,'北京');
insert into student values(20050005,'周华健','M','生物系',24,'山东');
insert into student values(20050006,'周润发','M','数学系',20,'湖北');--建立课程表
create table course
(cid number primary key ,--这是课程号cname varchar2(50) not null,--课程名ccredit number(3) --课程学分
);insert into course values(11,'java编程',6);
insert into course values(21,'c++课程',4);
insert into course values(31,'oracle',3);
insert into course values(41,'javaEE',100);
insert into course values(51,'linux',1);--建立选课表
create table studCourse
(stuCourseId number primary key ,--这是一个自增的,表示一次选课sid number  references student(sid),--学生号cid number references course(cid),--课程号grade number not null--成绩
);-- 建立选课序列
create sequence stucourse_seq
start with 1
increment by 1
minvalue 1
nomaxvalue
nocycle
nocache
;--初始化数据
insert into studCourse values(stucourse_seq.nextval,20040001,11,90);
insert into studCourse values(stucourse_seq.nextval,20040001,21,19);
insert into studCourse values(stucourse_seq.nextval,20050003,21,45);
insert into studCourse values(stucourse_seq.nextval,20050004,41,99);
insert into studCourse values(stucourse_seq.nextval,20050006,11,39);

PS:在设计表的时候,应当每张表都有一个主键,且该主键最好不含业务逻辑。

1、查询类的全部属性

基本语法:

from Domain类名

案例:

from Student -- 查询Student表中所有数据

2、查询类的部分属性

基本语法:

select 属性1,属性2 from Domain类名

案例:

select sname,sage from Student

3、取出单条记录

基本语法:

    session.createQuery(“from xxx where id=123456”).uniqueResult();

案例:

    Student s=(Student) session.createQuery("from Student where sid = 20050003").uniqueResult();

PS:如果检索一个对象,明确知道最多只有一个对象,则建议使用该方法。

4、过滤重复值

基本语法:

select distinct 属性1,属性2 from Domain类名

案例:

List list=session.createQuery("select distinct sage,ssex from Student").list();
for(int i=0;i<list.size();i++){Object []  objs=(Object[]) list.get(i);System.out.println(objs[0].toString()+" "+objs[1].toString());
}

PS:通过使用distinct可以过滤掉重复的数据。

5、取某个范围类的记录

基本语法:

[select 属性列表] from Domain类名 where 属性名 between 数值下界 and 数值上界

案例:

List list=session.createQuery("select distinct sage,ssex,sname from Student where sage between 20 and 22").list();
for(int i=0;i<list.size();i++){Object []  objs=(Object[]) list.get(i);System.out.println(objs[0].toString()+" "+objs[1].toString()+objs[2].toString());
}

6、存在或不存在与记录里

基本语法:

[select 属性列表] from Domain类名 where 属性名 in[not in](‘条件1’,’条件2’,’条件3’)

案例:

List<Student> list=session.createQuery("from Student where sdept in ('计算机系','外语系')").list();
//取出  for 增强
for(Student s:list){System.out.println(s.getSname()+" "+s.getSaddress()+" "+s.getSdept());
}

7、模糊查询

基本语法:

[select 属性列表] from Domain类名 where 属性名 like ‘字符串’

案例:

from Student where sname like ‘林%’

8、group by,having,order by,聚集函数使用

案例1:

//显示各个系的学生的平均年龄
List<Object[]> list=session.createQuery("select avg(sage),sdept from  Student group by sdept").list();
//取出1. for 增强
for(Object[] obj:list){System.out.println(obj[0].toString()+" "+obj[1].toString());
}

案例2:

//1.对分组查询后的结果,进行筛选:比如请显示人数大于3的系名称
//a. 查询各个系分别有多少学生.
List<Object[]> list=session.createQuery("select count(*) as c1,sdept from  Student group by sdept having count(*)>3").list();
//取出1. for 增强
for(Object[] obj:list){System.out.println(obj[0].toString()+" "+obj[1].toString());
}

案例3:

//2查询女生少于200人的系
//a.查询各个系的女生有多个个
List<Object[]> list=session.
createQuery("select count(*) as c1,sdept from Student where ssex='F' group by sdept").list();
//取出1. for 增强
for(Object[] obj:list){System.out.println(obj[0].toString()+" "+obj[1].toString());
}

案例4:

//1.查询计算机系共多少人?->如果我们返回的是一列数据
//这时我们的取法是直接取出list->object 而不是 list->Object[]
List<Object[]> list=session.createQuery("select sage from  Student where sdept='计算机系'").list();
//取出1. for 增强
for(Object obj:list){System.out.println(obj.toString());
}

案例5:

//3.查询选修11号课程的最高分和最低分.
List<Object[]> list=session.
createQuery("select 11,max(grade),min(grade) from Studcourse where course.cid=11").list();
//取出1. for 增强
for(Object[] obj:list){System.out.println(obj[0].toString()+" max="+obj[1].toString()+" min="+obj[2].toString());
}

案例6:

//计算各个科目不及格的学生数量
List<Object[]> list=session.createQuery("select count(*),student.sdept from Studcourse where grade<60 group by student.sdept").list();
//取出1. for 增强
for(Object[] obj:list){System.out.println(obj[0].toString()+" "+obj[1].toString());
}

PS:group by用于分组,having在分组后加限制条件,order by指定排序方式,聚集函数有count(),avg(),max(),min(),sum()五个,大部分内容和SQL中语法相似,给出以前相关内容的博客:Oracle表管理、Java数据库基础

9、实际应用之分页显示

public void showStuByPage(int pageSize,int pageNow){Query q = session.createQuery(“from Student”); q.setFirstResult((pageNow - 1) * pageSize); //从第几条取q.setMaxResult(pageSize);     //取出几条List list = q.list();         //执行   Iterator it=list.iterator();   //显示一下while(it.hasnext){Student s=(Student)it.next();System.out.println(s.getSname());System.out.println(s.getSage());} String hql=“select count(*) from Student”;list=session.createQuery(hql).list();int pageRow=((Integer)list.get(0)).intValue();int pageCount=(pageRow+pageSize-1)/pageSize;//总页数}

10、参数绑定

参数绑定的两种形式:

1、:参数名

基本语法:

Query q = session.createQuery(from Domain类名 where 属性1=:参数1);

q.setParameter(“参数1”, ”值1”);

案例:

    List<Student> list=session.createQuery("from Student where sdept=:a1 and sage >: sage").setString("a1", "计算机系").setString("sage", "2").list();

或者可以:

    Query q = session.createQuery("from Student where sdept=:a1 and sage >: sage"); q.setString("a1", "计算机系");q.setString("sage", "2");
2、“?”形式

基本语法:

Query q = session.createQuery(from Domain类名 where 属性1=?);

q.setParameter(“0”, ”值1”);

案例:

    List<Student> list = session.createQuery("from Student where sdept=? and sage>?").setString(0, "计算机系").setString(1, "2").list();

或者是:

    Query query=session.createQuery("from Student where sdept=? and sage>?");query.setString(0, "计算机系");query.setString(1, "2");List <Student> list=query.list();for(int i=0;i<list.size();i++){Student s= list.get(i);System.out.println(s.getSname()+" "+s.getSage());}

使用参数绑定的好处

1.可读性好.

2.性能提高.

3.防止sql注入.

11、在映射文件中得到HQL语句

案例:

在: Student.hbm.xml 中

<query name="myquerytest"><![CDATA[select sname,ssex from Student where sage>22]]>
</query>

使用方法:

List list=session.getNamedQuery("myquerytest").list();
System.out.println(list.size());
Iterator it=list.iterator();
while(it.hasNext()){Object obj[]=(Object[])it.next();System.out.println("n="+obj[0]);
}

PS:通过在映射文件中配置hql,可以使hql的查询更灵活。

12、子查询

案例:显示所有选择了21号课程的学生信息

from Student where sid in (select student.sid from StudCourse where course.cno='21')

13、多表查询

案例:显示林青霞选择的所有课程名和成绩

select s1.sname,s2.course.cid,c1.cname,s2.grade from Student as s1,StudCourse as s2,Course as c1 where s1.sname='林青霞' and s1.sname=s2.student.sname and c1.cid=s2.course.cid

或者

select s1.course.cname,s1.grade from Studcourse s1 where s1.student.sname='林青霞'

补充:Criteria的使用

案例:

//查询年龄大于10岁的学生 criteria
Session s=HibernateUtil.getCurrentSession();
Transaction tx=s.beginTransaction();
Criteria cri=s.createCriteria(Student.class);
//添加检索条件
cri.add(Restrictions.gt("sage", new Long(10)));
List<Student> list=cri.list();
for(Student s1: list){System.out.println(s1.getSname());
}
tx.commit();       

PS:Criteria的优点是更加面向对象,如果对hql语句不太了解的话可以使用。缺点是: 功能不如hql强大,而且hql是hibernate官方推荐使用的语句。

----------参考《韩顺平.hibernate从入门到精通》

Hibernate-HQL基础相关推荐

  1. Hibernate HQL基础 投影查询

    HQL中投影查询即查询一个持久化类的一个或多个属性值(不包括全部属性值),则需要使用HQL的select子句. 1.查询持久化对象的单一属性值    为查询持久化对象的一个属性值,在select子句后 ...

  2. Hibernate HQL基础 限定查询条件(这里面有各种条件查询)

    在HQL中可以使用表达式完成指定的运算或者作为限制查询结果的条件.如下表所示 |-----------------------------------------------------------| ...

  3. Hibernate HQL基础 调用数据库存储过程

    在Hibernate中也可以通过SQLQuery对象调用数据库的存储过程,但是要求存储过程必须返回一个结果集. 如在Oracle数据库的一个存储过程为: CREATE OR REPLACE PROCE ...

  4. org.hibernate.hql.ast.QuerySyntaxException: ? is not mapped

    2010-5-3 21:48:23 org.apache.catalina.core.StandardWrapperValve invoke 严重: Servlet.service() for ser ...

  5. Hibernate 学习笔记(二)—— Hibernate HQL查询和 QBC 查询

    目录 一.Hibernate 的 HQL 查询 1.1.查询所有数据 1.2.条件查询 1.3.排序查询 1.4.统计查询 1.5.分页查询 1.6.投影查询 二.Hibernate 的 QBC 查询 ...

  6. Hibernate hql 查询指定字段并获取结果集

    Hibernate hql 查询指定字段并获取结果集 在hibernate中,用hql语句查询实体类,采用list方法的返回结果为一个List,该List中封装的对象分为以下三种情况: 1.查询全部字 ...

  7. weblogic10异常:org.hibernate.hql.ast.HqlToken

    今天部署应用到WLS10上,在运行过程中出现 ClassNotFoundException: org.hibernate.hql.ast.HqlToken 错误weblogic异常退出. GOOGLE ...

  8. (转)Hibernate框架基础——一对多关联关系映射

    http://blog.csdn.net/yerenyuan_pku/article/details/52746413 上一篇文章Hibernate框架基础--映射集合属性详细讲解的是值类型的集合(即 ...

  9. org.hibernate.hql.ast.QuerySyntaxException: myaddressbook is not mapped

    用hibernate查询 显示如下信息: org.hibernate.hql.ast.QuerySyntaxException: myaddressbook is not mapped. [from ...

  10. ERROR org.hibernate.hql.internal.ast.ErrorCounter unexpected token: form 异常解决

    ERROR org.hibernate.hql.internal.ast.ErrorCounter unexpected token: form 异常解决 参考文章: (1)ERROR org.hib ...

最新文章

  1. LeetCode之283. Move Zeroes
  2. 全球第三位艾滋病痊愈者出现,靠脐带血干细胞新疗法抵抗病毒,此前已患病9年...
  3. 字符串匹配のKMP【专题@AbandonZHANG】
  4. 如何使用SQL Server Reporting Services将数据格式转换为有价值的数据集
  5. 渲染层网络层错误_网络层IP报文详解和IP的类别?
  6. HDU 6124 Euler theorem
  7. 使用 Azure CLI 创建 Windows 虚拟机
  8. 如何利用FL Studio中文版做出失真效果
  9. AIC准则选三个变量的r语言代码
  10. 计算机方面毕业生怎样写简历
  11. Android 如何在关于手机界面添加个图片
  12. Windows 远程桌面复制问题
  13. 线上引流获客渠道有哪些
  14. 苹果电脑自动键入密码_键入时控制上网本或笔记本电脑的触摸板
  15. 一种STM32F1系列+ESP8266使用MQTT连接阿里云的方法
  16. Android加载长图,仿微博长图滚动查看
  17. 计算机网络——各种时延的计算
  18. OKI C330dn 激光打印机驱动
  19. SSM毕设项目公交车辆保修信息系统a60ma(java+VUE+Mybatis+Maven+Mysql)
  20. Halcon快速读取点云的方法

热门文章

  1. java方法、方法重载
  2. Linux Crontab 定时任务 及 Ubuntu 中cron指令使用
  3. Nexus9刷机全纪录
  4. 【Python】一维数据格式化
  5. 编写高质量代码的50条黄金守则-Day 01(首选隐式类型转换)
  6. C#LeetCode刷题之#771-宝石与石头(Jewels and Stones)
  7. 对windows更多的理解
  8. 我对软件测试的理解以及我的职业规划
  9. SpringBoot-异常处理
  10. 5个Python特性 越早知道越好的