心得11-hibernate.的HQL语句

1. Hibernate查询介绍

Hibernate HQL查询、Criteria查询、调用存储过程

Hibernate事务管理和并发控制

Hibernate 延迟加载策略、抓取策略、一级二级缓存管理

Hibernate整合Struts

2. HQL介绍

HQL:Hibernate查询语言,它是Hibernate提供的一种面向对象的查询语言。

 (1)在查询语句中设定各种查询条件

 (2)支持动态绑定参数(类似sql语句中的预处理,?赋值)

(3)支持投影查询(纵向查询,后面会举例具体说明)、分页查询、连接查询、分组查询,子查询

(4) 内置了一些聚集函数

 Hibernate中的Query接口就是专门用来执行HQL语句的查询接口。

  HQL查询的主要步骤:

《1》.创建查询对象

Query query=session.createQuery(“from Dept”);

《2》.执行查询列出结果

 1)列出所有的结果

List<Dept> depts=query.list();

for(Dept dept:depts){…}

2)列出单个结果

Query query=session.createQuery(“from Dept where id=1”);

 query.setMaxResults(1);

   Dept dept=(Dept)query.uniqueResult();

3)迭代访问结果;使用情况较少,麻烦

Iterator<Dept> it=query.iterate();

While(it.hasnext()){

}

3. HQL基本语法:持久化类名区分大小写

 1)选择要查询的持久化类。

   String hql=“from Dept”

  Query  query=session.createQuery(hql);

  String hql=“from Dept as d”;

  as是其别名的意思,可以省略,后面举例会具体说明

2).针对选定属性创建一个类,提供以这两个属性为参数的构造方法,使用此类来封装查询结果。

  3)where 条件子句

•         String hqlString="from Dept d where d.createdTime>='2010-01-01'";

•         Query query=session.createQuery(hqlString);

•         String hqlString="from Dept d where d.name like'java%' and d.employees is not empty and d.createdTime<current_date()";

4).  绑定查询参数

•        按参数名字绑定,这里用到了方法链

String hql=“from  Dept where id>:id and name like:likeName”

List<Dept> dept=session.createQuery(hql).setLong(“id”,new Long(ingputID)).setString(“likeName”,”%”+inputName+”%”).list();

5)distinct 过滤重复值

Select distinct createTime from Dept

6)聚集函数(计数)

 select count(id) from Dept d

7)order by 排序(asc升序,desc降序)

From Dept d order by d.createdTime asc,d.name desc

8)group by 对记录分组

Select count(e) from Employee e group by e.dept;

9)having 对分组后数据进行条件过滤

Select e.dept.name from Eployee e group by e.dept having count(e)>1

4.其他知识点

分页查询

Query接口提供两个用于分批显示查询结果的方法

setFirstResult(int firstResult):在记录集中从第几条记录开始取数据。默认是0。

session.beginTransaction();

String hql = "from Employee";

List<Employee> empls =  session.createQuery(hql).setMaxResults(pageSize) .setFirstResult((pageNo - 1) * pageSize).list();

session.getTransaction().commit();

setMaxResults(int maxResults):设置每次查询返回的最大对象数。

批量修改和删除:直接通过SQL语句操作数据库,执行完后,当前session缓存中的数据与数据库中的数据不是同步的

String hql=“delete Dept as d where d.name like:likeName”;

Query query=session.createQuery(hql).setString(“likeName”,”%三%”);

int count= query.executeUpdate();

连接查询

•         Inner join (内连接)        left outer join(左外连接)   

•         Right outer join (右外连接)        full join(全连接)

String hql = "FROM Dept d JOIN d.employees e "

 + " WHERE d.name LIKE :likeName";

抓取连接查询 fetch与懒加载相对

抓取:是指从数据库加载一个对象数据时,同时把它所关联的对象和集合的数据一起加载出来,以便减少SQL语句的数据,从而提高查询效率。

From Dept d left join Fetch d.employees e where d.name like “%web%”

5. 以上知识点的案例的分析

package com.hbsi.one2many;

 

import java.util.HashSet;

import java.util.List;

import java.util.Set;

 

import org.hibernate.Query;

import org.hibernate.Session;

import org.junit.Test;

 

import com.hbsi.utils.HibernateSessionFactory;

 

public class AppHql {

   

   @Test

   public void find(){

      

      Session session = HibernateSessionFactory.getSession();

      

      /*//简单查询,返回结果为list

      Query query = session.createQuery("from Department");

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

      for(Department dep : list){

        System.out.println(dep.getDepId()+"---"+dep.getDepName());

      }

      

       */   

      

      /*//简单查询,返回结果为类对象

      String hql = "from Department where id>1";

      //setMaxResults(1)是设置最大查询结果为1 ,否则你后面用的uniqueResult()方法会出错,改方法返回的结果是唯一值。

      Query query = session.createQuery(hql).setMaxResults(1);

      Department dep = (Department) query.uniqueResult();

        System.out.println(dep.getDepId()+"---"+dep.getDepName());

      */

      

      /*//投影查询(即纵向查询,就是查找某一字段的记录),选择部分属性,list中的元素是:object[];由于使用较麻烦,所以实际开发中不建议使用映射查询

      String hql = "select depId,depName from Department";

      Query query = session.createQuery(hql);

      List list = query.list();

      for(int i=0;i<list.size();i++){

        Object[] obj = (Object[]) list.get(i);

        System.out.println(obj[0]+"---"+obj[1]);

        System.out.println("-----------------");

      }*/

      

      /*//通过一个类来封装部分查询的结果,简化操作,但是执行效率不高

      String hql = "select new com.hbsi.one2many.DepartRow(d.depId,d.depName) from Department d";

      Query query = session.createQuery(hql);

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

      for(DepartRow dr : list){

        System.out.println(dr.getId()+"-----"+dr.getName());

      }*/

      

      /*//查询某一个属性的时候不需要再封装多余的属性类了,直接返回一个该属性类型的list

      String hql = "select depName from Department";

      Query query = session.createQuery(hql);

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

      for(String s : list){

        System.out.println(s);

      }*/

      

      /*//查询包含员工的部门  is empty的应用

      String hql = "from Department d where d.emp is not empty ";

      Query query = session.createQuery(hql);

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

      for(Department d : list){

        System.out.println(d.getDepName());

        for(Employee e : d.getEmp()){

           System.out.println("|----"+e.getEmpName());

        }

      }*/

      

      //绑定查询参数 : ?的下标由0开始

      /*String hql = "from Department d where d.depId>? and depName=?";

      Query query = session.createQuery(hql);

      query.setInteger(0,1);

      query.setString(1,"软件系");

      List<Department> dep = query.list();

      for(Department d : dep){

        System.out.println(d.getDepId()+"----"+d.getDepName());

      }*/

      

      //通过名字  (:名字)这种方法是给条件赋名称的方法来避免不知道哪个问号赋的什么值

        /*String hql = "from Department d where d.depId>:ids and depName=:name";

      Query query = session.createQuery(hql).setInteger("ids",1).setString("name","软件系");

      List<Department> dep = query.list();

      for(Department d : dep){

        System.out.println(d.getDepId()+"----"+d.getDepName());

      }

       */ 

      

      //统计部门数,一般通过统计id数来达到功能,不推荐使用count(*);下面两种方法的后台sql语句一样

      /*String hql = "select count(depId) from Department";

      Query query = session.createQuery(hql);

      //方法一:通过获取总记录数统计

      List list = query.list();

      System.out.println(list.get(0));

      //方法二:uniqueResult方法获取到的是Lang类型,不是Integer类型,强转为Integer类型会出错

      Long dep = (Long) query.uniqueResult();

      System.out.println(dep);*/

      

      //统计各个部门员工人数   部门名 ,人数 ;这里统计的是人数,不是部门数

      /*String hql = "select e.dep.depName,count(e.empId) from Employee e group by e.dep having count(e.empId)>=1";

      Query query = session.createQuery(hql);

      List list = query.list();

      for(int i=0;i<list.size();i++){

        Object[] obj = (Object[]) list.get(i);

        System.out.print(obj[0]+"--");

        System.out.println(obj[1]);

      }*/

      

      //用hql语句删除用户,这里的hql删除的是数据库表中的数据,但是session缓存中还保留着数据;这里调用的是executeUpdate更新语句,所以要开启事务,否则会回滚导致数据库的数据也没有被删除

      /*session.beginTransaction();

      

      Employee e = (Employee) session.get(Employee.class,6);

      System.out.println(e.getEmpName());

      Query query = session.createQuery("delete Employee where empId=6");

      query.executeUpdate();

      System.out.println(e.getEmpName());

      session.getTransaction().commit();

      */

      

      //inner join   内连接;这里用到了like的模糊查询

      

       /*String hql = "from Department d join d.emp where d.depName like:likename";

      Query query = session.createQuery(hql).setString("likename", "%软件%");

      List list = query.list();

      for(int i=0;i<list.size();i++){

        Object[] obj = (Object[]) list.get(i);

        Department dep = (Department) obj[0];

        Employee emp = (Employee) obj[1];

        System.out.println(dep.getDepName());

        System.out.println("|---"+emp.getEmpName());

      }

      */   

      

      //left join 左连接

      /*String hql = "from Employee e join e.dep";

      Query query = session.createQuery(hql);

      List list = query.list();

      for(int i=0;i<list.size();i++){

        Object[] obj = (Object[]) list.get(i);

        Department dep = (Department) obj[1];

        Employee emp = (Employee) obj[0];

        System.out.println(dep.getDepName());

        System.out.println("|---"+emp.getEmpName());

      }*/

      

      //fetch 抓取;

        String hql = "from Department d join fetch d.emp";

      Query query = session.createQuery(hql);

      //这里用list集合会重复抓取,这时可以用set集合;但是用set不能保证表里的顺序了就

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

      Set<Department> set = new HashSet<Department>(list);

      for(Department d : set){

        System.out.println(d.getDepName());

        for(Employee e: d.getEmp()){           

           System.out.println("|---"+e.getEmpName());

        }

      }

       

      

      //简单连接,多表连接的时候,内连接,左右连接、抓取表中的空部门(没有对应雇员)都不显示出来,为了测试这个的原因

      /*Query query = session.createQuery("from Department");

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

      for(Department d : list){

        System.out.println(d.getDepName());

      }*/

      

      //测试分页

      /*List<Employee> list = findEmployee(2,2);

      for(Employee e : list){

        System.out.println(e.getEmpName());

      }

      

      HibernateSessionFactory.closeSession();*/

   }

   

   //分页

   public List<Employee> findEmployee(int nowPage,int pageSize){

      Session session = HibernateSessionFactory.getSession();

      session.beginTransaction();

   

      Query query = session.createQuery("from Employee");

      query.setFirstResult((nowPage-1)*pageSize);

      query.setMaxResults(pageSize);

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

 

      session.getTransaction().commit();

      HibernateSessionFactory.closeSession();

      return list;

   }

}


 

posted @ 2012-12-26 17:34  yangkai_keven  阅读(153)  评论(0编辑  收藏  举报