Hibernate Hql查询实例

来源:互联网 发布:java 开发棋牌类游戏 编辑:程序博客网 时间:2024/06/08 08:28

 Hibernate配备了一种非常强大的查询语言,这种语言看上去很像SQL。完整的HQL语句形式如下:Select/update/delete…… from …… where …… group by …… having …… order by …… asc/desc。同时需要注意的是在hql中关键字不区分大小写,通常小写,类的名称和属性名称必须区分大小写,按照实体的设计去写大小写。

    下面从实例入手去进一步说明HQL的语音的用法。


搭建测试环境:

    测试中建立一个Classes实体类里面包含属性:id、班级名称、以及学生。student实体类里面包含:id、姓名、创建时间以及班级。student与classes是多对一的关系。

实体类

[java] view plain copy
  1. public class Student {  
  2.     private int id;  
  3.     private String name;  
  4.     private Date createTime;  
  5.     private Classes classes;  
  6.     public Date getCreateTime() {  
  7.         return createTime;  
  8.     }  
  9.       
  10.     public Student() {  
  11.     }  
  12.       
  13.     public Student(int id, String name) {  
  14.         this.id = id;  
  15.         this.name = name;  
  16.     }  
  17.     public void setCreateTime(Date createTime) {  
  18.         this.createTime = createTime;  
  19.     }  
  20.       
  21.     public Classes getClasses() {  
  22.         return classes;  
  23.     }  
  24.     public void setClasses(Classes classes) {  
  25.         this.classes = classes;  
  26.     }  
  27.     public int getId() {  
  28.         return id;  
  29.     }  
  30.     public void setId(int id) {  
  31.         this.id = id;  
  32.     }  
  33.     public String getName() {  
  34.         return name;  
  35.     }  
  36.     public void setName(String name) {  
  37.         this.name = name;  
  38.     }  

[java] view plain copy
  1. public class Classes {  
  2.     private int id;  
  3.     private String name;  
  4.       
  5.     private Set students;  
  6.       
  7.     public Set getStudents() {  
  8.         return students;  
  9.     }  
  10.     public void setStudents(Set students) {  
  11.         this.students = students;  
  12.     }  
  13.     public int getId() {  
  14.         return id;  
  15.     }  
  16.     public void setId(int id) {  
  17.         this.id = id;  
  18.     }  
  19.     public String getName() {  
  20.         return name;  
  21.     }  
  22.     public void setName(String name) {  
  23.         this.name = name;  
  24.     }  
  25. }  

映射文件:

[java] view plain copy
  1. <hibernate-mapping>  
  2.     <class name="com.syq.hibernate.Classes" table="t_classes">  
  3.         <id name="id">  
  4.             <generator class="native"/>  
  5.         </id>  
  6.         <property name="name"/>  
  7.         <set name="students" inverse="true">  
  8.             <key column="classid"/>  
  9.             <one-to-many class="com.syq.hibernate.Student"/>  
  10.         </set>  
  11.     </class>  
  12. </hibernate-mapping>  

[html] view plain copy
  1. <hibernate-mapping>  
  2.     <class name="com.syq.hibernate.Student" table="t_student">  
  3.         <id name="id">  
  4.             <generator class="native"/>  
  5.         </id>  
  6.         <property name="name"/>  
  7.         <property name="createTime"></property>  
  8.         <many-to-one name="classes" column="classid"></many-to-one>  
  9.     </class>  
  10. </hibernate-mapping>  

1.简单属性查询

单一属性查询,返会属性结果集列表,元素类型和实体类中相应的类型一致

[java] view plain copy
  1. List students=session.createQuery("select name from Student").list();  


多个属性查询,多个属性查询返会对象数组,对象数组的长度取决于属性的个数,对象数组中元素的类型取决于属性在实体类中的类型

[java] view plain copy
  1. List students=session.createQuery("select id,name from Student").list();  


多个属性查询,也可以使用hql动态实例化Student对象,返回实体对象。

[java] view plain copy
  1. List students=session.createQuery("select new Student(id,name) from Student").list();  


2、实体对象查询

N + 1问题

    就是发出了N+1条sql语句。1:首先发出查询对象id列表的语句。N:根据id到缓存中查询,如果缓存中不存在与之匹配的数据,那么会根据id发出相应的sql语句

    利用Iterator会出现N+1条SQL语句

[java] view plain copy
  1. Iterator iterator=session.createQuery("from Student").iterate();  


    如果先使用List将数据查询到session中再使用Iterator进行查询,就不会产生N+1条SQL语句,原因是:list: 默认情况下list每次都会发出sql语句,list会将数据放到缓存中,而不利用缓存;iterate:默认情况下iterate利用缓存,如果缓存中不存在会出现N+1问题

[java] view plain copy
  1. List students=session.createQuery("from Student").list();  
  2.             for (Iterator iterator = students.iterator(); iterator.hasNext();) {  
  3.                 Student student = (Student) iterator.next();  
  4.                 System.out.println(student.getName());  
  5.             }  
  6.             System.out.println("---------------------------------------------");  
  7.             Iterator iterator=session.createQuery("from Student").iterate();  
  8.             while(iterator.hasNext()){  
  9.                 Student student=(Student)iterator.next();  
  10.                 System.out.println(student.getName());  
  11.             }  


3、条件查询

采用拼字符串的方式传递参数

[java] view plain copy
  1. List students = session.createQuery("select s.id, s.name from Student s where s.name like '%0%'").list();  


采用 “?”来传递参数(索引从0开始)

[java] view plain copy
  1. List students=session.createQuery("select s.id, s.name from Student s where s.name like ?")  
  2.             .setParameter(0"%0%")  
  3.             .list();  


采用 “:参数名” 来传递参数

[java] view plain copy
  1. List students=session.createQuery("select s.id, s.name from Student s where s.name like :myname")  
  2.             .setParameter(":myname""%0%")  
  3.             .list();  


传递多个参数采用setParamterList方法

[java] view plain copy
  1. List students=session.createQuery("select s.id, s.name from Student s where s.id in (?,?,?,?,?)")  
  2.             .setParameter(01)  
  3.             .setParameter(12)  
  4.             .setParameter(23)  
  5.             .setParameter(34)  
  6.             .setParameter(45)  
  7.             .list();  
    或者

[java] view plain copy
  1. List students=session.createQuery("select s.id, s.name from Student s where s.id in (:ids)")  
  2.             .setParameterList("ids"new Object[]{1,2,3,4,5})  
  3.             .list();  


hql中使用数据库的函数,如:date_format进行查询

[java] view plain copy
  1. List students=session.createQuery("select s.id, s.name from Student s where s.date_format(s.createTime,'%Y-%m')=? ")  
  2.             .setParameter(0"2009-08")  
  3.             .list();  

 

4、hibernate直接使用sql语句查询     

[java] view plain copy
  1. List students=session.createSQLQuery("select * from t_student").list();  


5、外置命名查询

    所谓的外置命名查询,就是将需要查询的sql语句以及条件写到映射文件中。

 1.在映射文件中使用<query>标签来定义hql

[html] view plain copy
  1. <query name="queryStudent">  
  2. <span style="white-space:pre">    </span><![CDATA[ 
  3.         select s from Student s where s.id<? 
  4.      ]]>  
  5. </query>  


 2.在程序中使用session.getNamedQuery()方法得到hql查询串

[java] view plain copy
  1. List students=session.getNamedQuery("queryStudent")  
  2.                     .setParameter(010)  
  3.                     .list();</span>  


6、过滤器查询

    过滤器查询在映射文件利用filter-def去定义一个过滤器,在过滤期中定义过滤器写条件。并在程序中为过滤器赋值。

 1.在映射文件中定义过滤器参数,在类的映射中使用过滤器参数

[html] view plain copy
  1. <class name="com.syq.hibernate.Student"table="t_student">  
  2.          <id name="id">  
  3.               <generator class="native"/>  
  4.          </id>  
  5.          <property name="name"/>  
  6.          <property name="createTime"></property>  
  7.          <many-to-one name="classes"column="classid"></many-to-one>  
  8.          <filter name="testFilter"condition="id < :myid"></filter>  
  9.      </class>  
  10.      <filter-def name="testFilter">  
  11.          <filter-param name="myid"type="integer"/>  
  12.      </filter-def>  

 2.在程序中必须显示的启用过滤器,并且为过滤器参数赋值

[java] view plain copy
  1. //启动过滤器,并给过滤器添加条件  
  2. session.enableFilter("testFilter").setParameter("myid"10);  
  3. List students=session.createQuery("from Student").list();  


7、分页查询

setFirstResult(),从0开始,setMaxResults(),每页显示的记录数

[java] view plain copy
  1. List students=session.createQuery("from Student")  
  2.                     .setFirstResult(1)  
  3.                     .setMaxResults(2)  
  4.                     .list();  


8、对象导航查询

[java] view plain copy
  1. List students=session.createQuery("from Student s where s.classes.name like " +  
  2.                     "'%2%'").list();  

9、连接查询

内连接

[java] view plain copy
  1. List students=session.createQuery("select s.name,c.name from Student s join s.classes c").list();  


左连接

[java] view plain copy
  1. List students=session.createQuery("select s.name,c.name from Student s left join s.classes c").list();  


右连接

[java] view plain copy
  1. List students=session.createQuery("select s.name,c.name from Student s right join s.classes c").list();  


10、统计查询

count

[java] view plain copy
  1. List list=session.createQuery("select Count(*) from Student").list();  
    或者直接返回统计数字
[java] view plain copy
  1. Long count=(Long)session.createQuery("select Count(*) from Student").uniqueResult();  

group分组

[java] view plain copy
  1. String hql="select c.name,count(s) from Classes c join c.students s group by c.name" ;  
  2. List students=session.createQuery(hql).list();  

    

    总之,可以利用hql进行灵活查询:进行条件查询、直接使用原生sql查询、外置名称查询、过滤器查询、分页查询、导航属性查询、连接查询、统计查询。但是所有的查询大多数都返回的是数组对象。只有使用“from student”语句、单一属性查询以及l动态实例化实体类对象的时候才能返回实体集合。

原创粉丝点击