Hibernate总的来说共有三种查询方式:HQL、QBC和SQL三种。但是细分可以有如下几种: 一、HQL查询方式 这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的语法差不太多。条件查询、分页查询、连接查询、嵌套查询,写起来与SQL 语法基本一致,唯一不同的就是把表名换成了类或者对象。其它的,包括一些查询函数(count(),sum()等)、查询条件的设定等,全都跟SQL语法 一样。 ###注意:
在hql中关键字不区分大小写,但是属性和类名区分大小写 示例1: static void query(String name){ Session s=null; try{ s=HibernateUtil.getSession(); //from后面是对象,不是表名 String hql="from Admin as admin where admin.aname=:name";//使用命名参数,推荐使用,易读。 Query query=s.createQuery(hql); query.setString("name", name); List<Admin> list=query.list(); for(Admin admin:list){ System.out.println(admin.getAname()); } }finally{ if(s!=null) s.close(); } }######!!!!!!!!!!!!!对于多对一关系查询: String hql = "from Student where Class.className = '二班'"; (Student实体类中含有Class对象的引用。这样相当于两张表的联合查询) 示例2(分页查询): Query query = session.createQuery("from Customer c order by c.name asc"); query.setFirstResult(0); query.setMaxResults(10); List result = query.list(); 说明: –setFirstResult(int firstResult):设定从哪一个对 象开始检索,参数firstResult表示这个对象在查询结果中的索引位置,索引位置的起始值为0。默认情况下,Query和Criteria接口从查 询结果中的第一个对象,也就是索引位置为0的对象开始检索。–setMaxResult(int maxResults):设定一次最多检索出的对象数目。默认情况下,Query和Criteria接口检索出查询结果中所有的对象。
适用情况:常用方法,比较传统,类似jdbc。缺点:新的查询语言,适用面有限,仅适用于Hibernate框架。二、QBC(Query By Criteria) 查询方式 这种方式比较面向对象方式,重点是有三个描述条件的对象:Restrictions,Order,Projections。使用QBC查询,一般需要以下三个步骤: 1、 使用Session实例 的createCriteria()方法创建Criteria对象 2、使用工具类Restrictions的方法为Criteria对象设置查询条件,Order工具类的方法设置排序方式,Projections工具类的方法进行统计和分组。 3、 使用Criteria对象的list()方法进行查询并返回结果 Restrictions类的常用方法:
Restrictions类的常用方法:
方法名称 | 描述 |
Restrictions.eq | 等于 |
Restrictions.allEq | 使用Map,Key/Valu进行多个等于的比对 |
Restrictions.gt | 大于 |
Restrictions.ge | 大于等于 |
Restrictions.lt | 小于 |
Restrictions.le | 小于等于 |
Restrictions.between | 对应SQL的between |
Restrictions.like | 对应SQL的like |
Restrictions.in | 对应SQL的in |
Restrictions.and | and关系 |
Restrictions.or | or关系 |
Restrictions.sqlRestriction | SQL限定查询 |
Order类的常用方法:
方法名称 | 描述 |
Order.asc | 升序 |
Order.desc | 降序 |
Projections类的常用方法
方法名称 | 描述 |
Projections.avg | 求平均值 |
Projections.count | 统计某属性的数量 |
Projections.countDistinct | 统计某属性不同值的数量 |
Projections.groupProperty | 指定某个属性为分组属性 |
Projections.max | 求最大值 |
Projections.min | 求最小值 |
Projections.projectionList | 创建一个ProjectionList对象 |
Projections.rowCount | 查询结果集中的记录条数 |
Projections.sum | 求某属性的合计 |
八、Query.iterator的N+1查询(基于一的HQL,多见于一对多、多对多的关联映射) N + 1问题,在默认情况下,使用query.iterate查询,有可以能出现N+1问题 所谓的N+1是在查询的时候发出了N+1条sql语句 1: 首先发出一条查询对象id列表的sql N: 根据id列表到缓存中查询,如果缓存中不存在与之匹配的数据,那么会根据id发出相应的sql语句* list和iterate的区别? * list每次都会发出sql语句,list会向缓存中放入数据,而不利用缓存中的数据 * iterate:在默认情况下iterate利用缓存数据,但如果缓存中不存在数据有可以能出现N+1问题 示例:Query q=session.createQuery(“from UserInfo”); Iterator<UserInfo> list=q.iterate(); While(list.hasNext()) { UserInfo st = (UserInfo) it.next(); System.out.println(st.getName()); }避免N+1查询解决方法: 1、可以将fetch抓取数据的属性改为“join”,来避免N+1次的查询; 2、使用二级缓存九、复查查询(基于二:QBC的深度查询) 复合查询就是在原有查询的基础上再进行查询,可以调用Criteria对象的createCriteria()方法在这个Criteria对象的基础上再进行查询。 示例:Session session = SessionFactory.getCurrentSession(); User user = new User(); Transaction ts = session.beginTransaction(); try { Criteria criteria1 = session.createCriteria(Room.class); Criteria criteria2 =criterial.createCriteria("User"); criteria2.add(Restrictions.eq("name",new String("ijse")); user= (User) criteria.list().get(0); session.commit(); } catch (HibernateException ex) { ts.rollBack(); ex.printStackTrace(); } System.out.println(user.getName());
原文地址: http://blog.sina.com.cn/u/2147192277