Hibernate(一)HQL查询、原生sql查询

          hibernate中支持三种查询方式:HQL(Hibernate Query Language)原生sql查询Criteria查询HQL是一种面向对象的查询语言,其中没有表和字段的概念,只有类、对象、属性的概念;原生sql查询就是我们程序员手动的写sql语句并执行;Criteria查询又称为对象查询,采用真正的面向对象的方式进行查询,Criteria查询将在后续篇章中进行单独讲解,本篇文章只讲解HQL查询和原生sql查询。

        环境:
            本篇及后续文章都将使用Oracle数据库oracle自带的两张数据表Dept和Emp以及Hibernate4为例进行讲述

一、HQL查询

1.HQL语句的组成
①from子句

最为简单的查询语句,比如:

  1. from Dept  

②select子句
主要用于选取对象的属性(投影),如:

  1. select deptNo from Dept  
        详细将在后续讲解
③where子句
用于添加查询条件,如:
  1. from Dept where deptNo=2  
④表达式
一般用在where子句中,如:
  1. from Dept where lower(deptName)='sales'  
⑤order by 子句
用于按照指定属性进行排序,如:
  1. from Emp order by hireDate asc  
注意:

       a.from后面跟的都不是表的名字,而是表对应的实体类的名字,必须完全一致;相应的,语句中的deptName、deptNo等都是 实体类属性的名字,而不是表中列的名字
       b.可以为实体类起别名,如:from Dept d where d.deptNo=2
       c.select、from、where...等关键词不区分大小写,实体类和属性名要完全一致

2.执行HQL语句
介绍了如何编写HQL语句,下面来介绍下如何来执行。HQL的查询是通过Hibernate的Query接口来实现的

  1. //准备HQL语句  
  2.     String hql="from Dept";  
  3.     //使用createQuery()方法来创建Query接口实现类  
  4.     Query query=session.createQuery(hql);  
这里可以使用两种方式进行查询:
①使用list()方法
  1. public static void main(String[] args) {  
  2.         Session session=HibernateUtil.currentSession();  
  3.         Transaction tx=session.beginTransaction();  
  4.           
  5.         //准备HQL语句  
  6.         String hql="from Dept";  
  7.         //使用createQuery()方法来创建Query接口实现类  
  8.         Query query=session.createQuery(hql);  
  9.         List<Dept> list=query.list();  
  10.         for (Dept dept : list) {  
  11.             System.out.println(dept.getDeptNo()+"\t"+dept.getDeptName());  
  12.         }  
  13.           
  14.         tx.commit();  
  15.         HibernateUtil.closeSession();  
  16.     }  
运行结果:
Hibernate: 
   select
             dept0_.DEPTNO as DEPTNO0_,
             dept0_.DNAME as DNAME0_,
             dept0_.LOC as LOC0_ 
   from
              MYDEPT dept0_
50 vacant
60 test2
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS

②使用iterate()方法
  1. public static void main(String[] args) {  
  2.         Session session=HibernateUtil.currentSession();  
  3.         Transaction tx=session.beginTransaction();  
  4.           
  5.         //准备HQL语句  
  6.         String hql="from Dept";  
  7.         //使用createQuery()方法来创建Query接口实现类  
  8.         Query query=session.createQuery(hql);  
  9.         Iterator<Dept> list=query.iterate();  
  10.         Dept dept=null;  
  11.         while (list.hasNext()) {  
  12.             dept = list.next();  
  13.             System.out.println(dept.getDeptNo()+"\t"+dept.getDeptName());  
  14.         }  
  15.           
  16.         tx.commit();  
  17.         HibernateUtil.closeSession();  
  18.     }  
运行结果:
Hibernate: 
   select
             dept0_.DEPTNO as col_0_0_ 
   from
             MYDEPT dept0_
Hibernate: 
   select
              dept0_.DEPTNO as DEPTNO0_0_,
              dept0_.DNAME as DNAME0_0_,
              dept0_.LOC as LOC0_0_ 
   from
              MYDEPT dept0_ 
   where
               dept0_.DEPTNO=?
10 ACCOUNTING
Hibernate: 
   select
            dept0_.DEPTNO as DEPTNO0_0_,
            dept0_.DNAME as DNAME0_0_,
            dept0_.LOC as LOC0_0_ 
   from
            MYDEPT dept0_ 
   where
            dept0_.DEPTNO=?
20 RESEARCH
.
.
.

          从生成的sql语句可以看出,使用list()方法是先查询所有符合条件的记录;而iterate()方法是首先查询出所有符合条件的主键值(如:deptNo),然后在需要某一对象的其他

属性值的时候再发送sql语句进行查询;  

         这就是Hibernate的HQL查询,关于where子句、order by等子句的使用就不做过多的解释了(条件查询的参数传递可以留作疑问)大同小异,童鞋们可以自己去多试试,多练练。

二、原生sql查询

                  Hibernate为HQL查询生成了标准的sql查询语句,适用于所有的数据库平台,所以 HQL查询可以跨平台;但是有时候有可能需要使用底层数据库的特性,来进行特殊的查询,这时候原生sql查询就派到了用场。
                  原生sql查询同样使用了Query接口,使用session.createSQLQuery()方法可以返回一个SQLQuery对象,SQLQuery接口继承了Query接口在原生sql查询中就要对应的写表名和对应的列名了,而不是实体类和属性名,下面看依照HQL查询进行编码:
  1. public static void main(String[] args) {  
  2.         Session session=HibernateUtil.currentSession();  
  3.         Transaction tx=session.beginTransaction();  
  4.           
  5.         //编写sql语句  
  6.         String sql="select * from dept";  
  7.         //使用createSQLQuery()方法  
  8.         Query query=session.createSQLQuery(sql);  
  9.         List<Dept> list=query.list();  
  10.         for (Dept dept : list) {  
  11.             System.out.println(dept.getDeptNo()+"\t"+dept.getDeptName());  
  12.         }  
  13.           
  14.         tx.commit();  
  15.         HibernateUtil.closeSession();  
  16.     }  
                运行结果:
Hibernate: 
                 select
                              * 
                  from
                          dept
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.wzj.entity.Dept
at com.wzj.test.TestMain.main(TestMain.java:43)
              诶,这时候发生了异常!控制台输出了类型转换异常,这又是为什么呢?看异常信息,它说不能将Ljava.lang.Object这个类型转换成Dept类型 这个L代表数组的意思,是说不能将对象数组类型转换成Dept类型。
              是的, 使用原生sql查询查询出来的是关系型数据,是Object[]类型,而不是像HQL查询那样直接封装成了Dept对象,所以应该这样写:
  1. //编写sql语句  
  2.     String sql="select * from dept";  
  3.     //使用createSQLQuery()方法  
  4.     Query query=session.createSQLQuery(sql);  
  5.     List<Object[]> list=query.list();  
  6.     for (Object[] dept : list) {  
  7.         System.out.println(dept[0]+"\t"+dept[1]);  
  8.     }  
这样写的话就会的得到查询结果。
①转换查询数据
        为了使查询的数据直接封装成Dept对象,Hibernate的 SQLQuery接口提供了addEntity()方法来将关系数据转换成对象型数据:
  1. //编写sql语句  
  2.     String sql="select * from dept";  
  3.     //注意addEntity()方法是SQLQuery接口特有的,使用query是调用不出来的  
  4.     Query query=session.createSQLQuery(sql).addEntity(Dept.class);  
  5.     List<Dept> list=query.list();  
  6.     for (Dept dept : list) {  
  7.         System.out.println(dept.getDeptNo()+"\t"+dept.getDeptName());  
  8.     }  
②连接查询
此外, SQLQuery接口还提供了addJoin()方法来进行连接查询:
  1. String sql="select e.*,d.* from EMP e join DEPT d on d.deptno=e.deptno";  
  2.     Query query=session.createSQLQuery(sql).addEntity("e",Emp.class)  
  3.                     .addJoin("d","e.dept");  
  4.     //连接查询返回Object数组类型,第一个是元素是Emp对象,第二个是Dept对象  
  5.     List<Object[]> list=query.list();  
  6.     Emp emp=null;  
  7.     Dept dept=null;  
  8.     for (Object[] o : list) {  
  9.         emp=(Emp)o[0];  
  10.         dept=(Dept)o[1];  
  11.         System.out.println(emp.getEmpName()+"\t"+dept.getDeptName());  
  12.     }  

运行结果:
            Hibernate: 
                   select
                               e.*,
                               d.* 
                   from
                                EMP e 
                   join
                                DEPT d 
                   on d.deptno=e.deptno
CLARK ACCOUNTING
KING ACCOUNTING
MILLER ACCOUNTING
JONES RESEARCH
FORD RESEARCH
ADAMS RESEARCH
SMITH RESEARCH
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值