Hibernate 笔记 HQL查询

时间:2022-02-28 14:55:54

http://www.cnblogs.com/zilong882008/archive/2011/11/05/2237123.html

Hibernate 笔记 HQL查询(一)单属性,多属性查询

HQL是Hiberante官方推荐的Hibernate检索方式,它使用类似SQL的查询语言,以面向对象的方式从数据库中查询。可以使用HQL查询具有继承、多态和关联关系的数据。在检索数据时应优先考虑使用HQL方式。

本笔记将会沿用前面所使用的dept部门表,emp员工表。

dept部门表

Hibernate 笔记 HQL查询

emp员工表

Hibernate 笔记 HQL查询

1 查询实体

     hibernate的session.createQuery()方法是使用HQL语句查询对象的。

     hql:是查询对象的,例如:"from User",其中from不区分大小写,而User是区分大小写,因为它是对象。是User类

     返回Query对象。

     执行这条语句后,Hibernate会根据配置文件中所配置的数据库适配器自动生成相应数据库的SQL语句。

sql: select * from dept;     from 后面是表名

hql: form Dept;    from 后面是类。

可以对类起别名,有两种方法。

hql: from Dept d

hql:from Dept as d

以上两种起别名方法皆可。

Hibernate 笔记 HQL查询
public void Test1() throws Exception{   
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();
String hql="from Dept"; //定义String类型hql,写入hql语句。
Query query=session.createQuery(hql);

List<Dept> list = query.list();
for(Dept dept:list){
System.out.print("部门编号: "+dept.getDid() +" ");
System.out.println("部门名称: "+dept.getDname());

}
tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

执行结果

Hibernate: select dept0_.did as did1_, dept0_.dname as dname1_, dept0_.daddress as daddress1_ from dept dept0_
部门编号:  1   部门名称:   业务部
部门编号:  2   部门名称:   技术部
部门编号:  3   部门名称:   管理部
部门编号:  4   部门名称:   财务部
部门编号:  5   部门名称:   人力资源部

 

2  查询表中单个属性

sql: select ename from dept

hql: select ename from Dept

对属性也可以设置别名

hql:select ename as from Dept

as 必须加。

Hibernate 笔记 HQL查询
    public void Test2() throws Exception{ 
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();
Query query=session.createQuery("select dname from Dept");
List<String> list = query.list();
for(String name:list){
System.out.println("部门名称: "+name);
}
tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

 

 执行结果

Hibernate: select dept0_.dname as col_0_0_ from dept dept0_
部门名称: 业务部
部门名称: 技术部
部门名称: 管理部
部门名称: 财务部
部门名称: 人力资源部

3  对多个属性进行查询

sql: select ename,eage from emp

hql:select ename,eage from Emp

hql: select e.ename,e.eage from Emp e

以上两种hql写法均可。

Hibernate 笔记 HQL查询
public void Test3() throws Exception{
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();
Query query=session.createQuery("select ename,eage from Emp");
List<Object[]> list = query.list(); //对多个属性查询的时候,使用Obejct数组。

for(Object[] message:list){
System.out.println(Arrays.toString(message)); //采用辅助类Arrays的toString()方法打印数组。
}
tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

 

测试结果

Hibernate: select emp0_.ename as col_0_0_, emp0_.eage as col_1_0_ from emp emp0_
[刘德华, 40]
[李世民, 34]
[曹操, 59]
[和珅, 44]
[贺龙, 45]
[郭富城, 34]

4 通过实体类方式查询多属性

除了上述方法外,还可以采用实体类的方式查询,要在Emp类中加入带有查询参数的构造器,代码如下。

Hibernate 笔记 HQL查询
public class Emp {
private int eid;

private int eage;

private float esal;
private String ename;
   省略get,set方法。


public Emp() {
super();
}
public Emp(int eage, String ename) { //需要查询的属性是什么,构造器的参数就是什么。
super();
this.eage = eage;
this.ename = ename;
}
Hibernate 笔记 HQL查询

 

 

测试类

Hibernate 笔记 HQL查询
public void Test4() throws Exception{ 
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();
Query query=session.createQuery("select new Emp(eage,ename) from Emp e"); select 后直接调用构造器,参数就是查询的属性,参数不可错乱。
List<Emp> list = query.list(); 此处不实用object数组,类类型即可
for(Emp message:list){
System.out.print("姓名:"+message.getEname()+" ");
System.out.println("年龄:"+message.getEage());
}
tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

测试结果

Hibernate: select emp0_.eage as col_0_0_, emp0_.ename as col_1_0_ from emp emp0_
姓名:刘德华  年龄:40
姓名:李世民  年龄:34
姓名:曹操  年龄:59
姓名:和珅  年龄:44
姓名:贺龙  年龄:45
姓名:郭富城  年龄:34

http://www.cnblogs.com/zilong882008/archive/2011/11/05/2237243.html

Hibernate 笔记 HQL查询(二)条件查询,聚集函数,子查询,导航查询

本笔记继续使用dept部门表,emp员工表,一对多多对一双向映射。

1 条件查询

1.1    查询 员工表emp中 年龄eage小于30,月薪esal大于20000的员工姓名ename

sql:select ename from emp where eage<? and esal >?;

hql: select ename from Emp where eage<? and esal >?

1.2 问号的设置与别名

 问号(?)的设置使用.setParameter(位置, 属性值) 在sql语句中问号的位置是从1开始,在hql中从零开始。

 在hql中,问号(?)也可以起别用,:后面紧跟别名,setParameter("age", 30)方法也随之改变,将原先的数字改成"别名",如下所示

             String hql="select ename from Emp where eage<:age and esal >:sal";
             Query query= session.createQuery(hql).setParameter("age", 30).setParameter("sal", 20000f).list();   

1.3   一组问号的设置

       对于一组问号也可以设置别名:如 查询在1,2部门的员工姓名

             hql="select ename from Emp where did in (?,?)";

             hql="select ename from Emp where did in (:d)";

             Query query= session.createQuery(hql).setParameter("d", new Object[]{1,2}).list();

 

Hibernate 笔记 HQL查询
public void Test9() throws Exception{ 
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();
String hql="select ename from Emp where eage<? and esal >?";
Query query= session.createQuery(hql).setParameter(0, 30).setParameter(1, 20000f); //设置问号,从0开始。
List<String> list = query.list();
for(String message:list){
System.out.println(message);
}
tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

结果:

Hibernate: select emp0_.ename as col_0_0_ from emp emp0_ where emp0_.eage<? and emp0_.esal>?
刘亦菲
白百何
文章
林月如

 

2 条件查询的常用关键字

    2.1  distinct  过滤重复的值

            查询员工表中的所有员工姓名,并去掉重复值

            hql="select distinct  ename from Emp ";  

    2.2  delete   删除

             删除年龄大于25的员工

     hql="delete Emp where eage>25"; 删除年龄大于25岁的用户

            Query query=session.createQuery(hql);

         query.executeUpdate();           //执行  executeUpdate 方法返回int类型。

       tx.commit();            //成功,则提交,对数据库操作

    2.3  update 更新

           更新员工编号11的年龄为22

    String hql="update Emp s set s.eage='22' where s.eid=11";   //更新语句

       Query query=session.createQuery(hql);

           query.executeUpdate();           //执行

           tx.commit();           //成功,则提交

    2.4  between...and...和not between... and...确定查询范围

          查找员工表中年龄在20到30之间的员工姓名

          hql="select ename from Emp where eage between 20 and 30"

  2.5  in和not in确定查询集合

           查询员工属于低1,2部门的员工姓名

          hql="select ename from Emp where did in(1,2)"

    2.6  like进行模糊查询

          用like进行模糊查询时有两个可用的通配符:“%”和“_”。“%”代表长度大于等于0的字符,“_”代表长度为1的单个字符。

          查询员工表中姓名中带有刘的员工

          hql="select ename from Emp where ename  like '%刘%'"

     2.7  逻辑与 and 逻辑或 or

          查询员工中薪水大于2000 同时年龄小于30的员工姓名

          hql="select ename from Emp where esal>2000 and eage<30";

          查询员工中,年龄大于40或者年龄小于30的员工

          hql="select ename  from Emp where eage>40 or eage<30";

     2.8  order by对结果进行排序

         对薪水进行排序,从小到大

         hql="select esal from Emp where order by esal asc";

         对年龄进行排序,倒叙,

         hql="select ename from Emp where order by eage desc";

     2.9  group by对记录进行分组

        根据部门分组,求出各组的平均薪水

        hql=" select avg(esal) from Emp group by did";

     2.10 having 对分组进行筛选

          根据部门分组,查出员工所在组平均薪水大于10000的员工姓名

          hql=" select ename from Emp group by did having  avg(esal)>10000";

 

3 聚集函数

查询emp员工表中有多少个员工。

sql:select count(ename) from emp;

hql: select count(ename) from Emp;

聚集函数及含义:

Hibernate 笔记 HQL查询

hql: select avg(esal) from Emp;   薪水平均值

hql: select max(esal) from Emp;  薪水最大值

hql: select sum(esal) from Emp;  薪水最小值

Hibernate 笔记 HQL查询
    public void Test91() throws Exception{ 
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();
String hql="select count(ename) from Emp";
Object count=session.createQuery(hql).uniqueResult(); //uniqueResult()方法返回Object类型 
System.out.println(count);

tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

 

结果:

Hibernate: select count(emp0_.ename) as col_0_0_ from emp emp0_
15

 

 4 子查询

Hibernate 支持子查询,所谓子查询就是,要查询的字段及信息在A表,条件在B表。语法与sql语句相似。

Hibernate 笔记 HQL查询
public void Test9() throws Exception{ 
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();

String hql="select ename from Emp where did in (select did from Dept where daddress = 302)";
Query query= session.createQuery(hql);
List<String> list = query.list();
for(String message:list){
System.out.println(message);
}
tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

结果:

Hibernate: select emp0_.ename as col_0_0_ from emp emp0_ where did in (select dept1_.did from dept dept1_ where dept1_.daddress=302)
李世民
曹操
和珅
刘诗诗

 

5 导航查询

 e.dept.daddress=301

员工所在部门的地址是301

Hibernate 笔记 HQL查询
public void Test9() throws Exception{ 
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();

String hql="select ename from Emp e where e.dept.daddress=301 ";
Query query= session.createQuery(hql);
List<String> list = query.list();
for(String message:list){
System.out.println(message);
}
tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

结果:

Hibernate: select emp0_.ename as col_0_0_ from emp emp0_, dept dept1_ where emp0_.did=dept1_.did and dept1_.daddress=301
刘德华
贺龙
白百何
文章
林月如

http://www.cnblogs.com/zilong882008/archive/2011/11/06/2237808.html

Hibernate 笔记 HQL查询(三) 分页,表连接,批量更新,引用SQL

1 分页

      setFirstResult(0),(0开始)

    setMaxResults(5),每页显示5条数据

Hibernate 笔记 HQL查询
    public void Test1() throws Exception{ 
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();

String hql="select eage from Emp order by eage";
Query query= session.createQuery(hql).setFirstResult(0).setMaxResults(5); //从0开始,现实5条数据。
List<Integer> list = query.list();
for(Integer message:list){
System.out.println(message);                      
}                                     
tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

Hibernate: select emp0_.eage as col_0_0_ from emp emp0_ order by emp0_.eage limit ?
21
21
24
24
24

2 表连接

Hibernate 支持内链接和外链接(左连接,右连接)

hql: from Emp e  inner join fetch e.dept;   内链接

hql: from Emp e  left join fetch e.dept;     左连接

hql:from Emp e right join fetch e.dept     右连接

Hibernate 笔记 HQL查询
public void Test2() throws Exception{   //实体
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();
Query query=session.createQuery("from Emp e inner join fetch e.dept where eage<30");

List<Emp> list = query.list();

for(Emp user:list){
System.out.println(user.getEname());
System.out.println(user.getDept().getDaddress());
tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

结果

Hibernate: select emp0_.eid as eid2_0_, dept1_.did as did1_1_, emp0_.ename as ename2_0_, emp0_.eage as eage2_0_, emp0_.esal as esal2_0_, emp0_.did as did2_0_, dept1_.dname as dname1_1_, dept1_.daddress as daddress1_1_ from emp emp0_ inner join dept dept1_ on emp0_.did=dept1_.did where eage<30
白百何
301
文章
301
林月如
301
刘诗诗
302

3 批量更新

将年龄在25岁一下的员工改成25岁

hql="update Emp e set e.eage=25 where e.eage<25";

删除25岁一下的员工

hql="delete Emp e where e.eage<25";

使用executeUpdate()方法必须启用事务。

Hibernate 笔记 HQL查询
public void Test3() throws Exception{ 
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();
String hql="update Emp e set e.eage=25 where e.eage<25";
Query query=session.createQuery(hql);
query.executeUpdate();

tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}
Hibernate 笔记 HQL查询

 

4 Hibernate 中使用SQL

HQL不是万能的,无法执行插入语句和非常复杂的查询,Hibernate 也支持SQL查询。通过连接直接调用cerateSQLQuery(sql)即可

sql语句中存在问号,同样使用setParameter(位置,属性值)方法设置。问号的位置从0开始,最后调用executeUpdate执行。事务提交后数据库开始工作。

Hibernate 笔记 HQL查询
public void Test4() throws Exception{ 
Configuration config=new Configuration().configure();
SessionFactory sessionFactory= config.buildSessionFactory();
Session session=null;
Transaction tr=null;
try{
session= sessionFactory.openSession();
tr=session.beginTransaction();
String sql="insert into emp (ename,eage) values (?,?)";
session.createSQLQuery(sql).setParameter(0, "曹雪芹").setParameter(1, 22).executeUpdate();
tr.commit();
}catch(Exception e){
tr.rollback();
}finally{
if(session!=null){
session.close();
}
if(sessionFactory!=null){
sessionFactory.close();
}
}
}