心得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; } }