栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Hibernate hql查询代码实例

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Hibernate hql查询代码实例

本文研究的主要是Hibernate hql查询的相关内容,具体如下。

HQL介绍

Hibernate语言查询(Hibernate Query Language,HQL)它是完全面向对象的查询语句,查询功能非常强大;具备多态、关联等特性,HQL查询也是Hibernate官方推荐使用的查询方法。

下面我们通过一个案例我分析相关查询方法

Classes.java:

public class Classes {
	
	private int id;
	
	private String name;
	
	private Set students;
	//省略setter和getter方法
}

Student.java:

public class Student {
	
	private int id;
	
	private String name;
	
	private Classes classes;
	//省略setter和getter方法
}

Classes.hbm.xml:

 
 
 
   
   
     
       
     
     
     
     
 
       
     
   
 

Student.hbm.xml:

 
 
 
   
     
       
     
     
     
     
     
   
 
1.查询单一属性:
 
      List students = session.createQuery("select name from Student").list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 String name = (String)iter.next(); 
 System.out.println(name); 
      } 

注:查询单一属性的时候,返回的是一个集合,集合元素的类型是该属性的类型。

2.查询多个属性,返回对象数组:
 
      List students = session.createQuery("select id, name from Student").list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[])iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      } 

注:查询多个属性返回的是一个类型为对象数组的集合,这个很好理解,当查询单一属性是返回的集合元素类型就是属性的类型,但是多个类型呢?那必须是对象数组来处理啊即Object[]。

3.查询多个属性,返回对象类型的集合:
 
      List students = session.createQuery("select new Student(id, name) from Student").list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Student student = (Student)iter.next(); 
 System.out.println(student.getId() + ", " + student.getName()); 
      } 

注:除了我们第二种方式返回的是一个对象数组,我们还可以给实体对象设置对应的构造函数,然后通过查询对象的方式进行查询,然后返回的就是实体类型的集合。

4.使用别名进行查询:
 
      List students = session.createQuery("select s.id, s.name from Student s").list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[])iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      } 
5.查询实体对象:
 
      List students = session.createQuery("from Student").list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Student student = (Student)iter.next(); 
 System.out.println(student.getName()); 
      }

注:查询实体可以直接使用from 类名的形式。

 
      List students = session.createQuery("select s from Student s").list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Student student = (Student)iter.next(); 
 System.out.println(student.getName()); 
      }

注:如果要使用select关键字,那么就必须使用别名。另外一点千万要注意:hql不支select * 的形式。

6.N+1问题:
 
      List students = session.createQuery("from Student").list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Student student = (Student)iter.next(); 
 System.out.println(student.getName()); 
      }

注:使用.list()的方式进行对象查询,只会发出一条语句,即取得实体对象数据的语句。

 
      Iterator iter = session.createQuery("from Student").iterate(); 
       
      while (iter.hasNext()) { 
 Student student = (Student)iter.next(); 
 System.out.println(student.getName()); 
      } 

注:通过iterator()方式进行对象查询,会发出N+1条语句,首先会发出一条语句查询出实体对象的ID,然后在根据各自的ID发出N条语句去查询N个对象,这中形式性能是比较差的。

 
      List students = session.createQuery("from Student").list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Student student = (Student)iter.next(); 
 System.out.println(student.getName()); 
      } 
      System.out.println("-----------------------------------------------------"); 
       
      Iterator iter = session.createQuery("from Student").iterate(); 
       
      while (iter.hasNext()) { 
 Student student = (Student)iter.next(); 
 System.out.println(student.getName()); 
      } 

注:其实Hibernate提供iterator()的方式查询是为了提高性能的,那为什么反而帮了倒忙呢?原因是iterator()是从一级缓存中取数据的,如果缓存中有数据,那么它的效率毫无疑问会相当的给力,但是当我第一次查询的时候缓存中怎么可能会有数据呢,所以就导致了所谓的N+1问题。上面这段代码可以避免N+1问题,它的思路是先用list()进行查询,因为list()查询出来以后,在一级缓存汇总就存在了数据,使用iterator()的时候,效率就会非常的高。

7.条件查询:
 
      List students = session.createQuery("select s.id, s.name from Student s where s.name like '%0%'").list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[])iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      }

注:条件查询和原生的sql相同,都是where关键字。另外通常使用别名比较方便,上述程序是查询多个属性,所以返回的是对象数组类型的集合,对象数组中的元素就是对应的属性。

8.占位符的形式查询:
 
      List students = session.createQuery("select s.id, s.name from Student s where s.name like ?") 
   .setParameter(0, "%0%") 
   .list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[])iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      } 

注:可以通过占位符的形式进行传参,这种方式可以防止SQL注入。

9.自定义参数的形式:
 
      List students = session.createQuery("select s.id, s.name from Student s where s.name like :myname") 
   .setParameter("myname", "%0%") 
   .list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[])iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      } 

注:like :myname冒号后面是没有空格的,否则会出错。

10.查询条件为in的形式:
[java] view plain copy
 
      List students = session.createQuery("select s.id, s.name from Student s where s.id in(:ids)") 
   .setParameterList("ids", new Object[]{1, 2, 3, 4, 5}) 
   .list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[])iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      }

注:in后面的括号中只要有一个形参即可,我们设置参数值的时候,可以通过对象数组就行传值。

11.使用数据库个性化函数:
 
      List students = session.createQuery("select s.id, s.name from Student s where date_format(s.createTime, '%Y-%m')=?") 
   .setParameter(0, "2009-08") 
   .list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[])iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      } 
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
       
      List students = session.createQuery("select s.id, s.name from Student s where s.createTime between ? and ?") 
   .setParameter(0, sdf.parse("2009-08-01 00:00:00")) 
   .setParameter(1, sdf.parse("2009-08-20 23:59:59")) 
   .list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[])iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      }
12.使用原生态的SQL语句:
 
      List students = session.createSQLQuery("select * from t_student").list(); 
       
      for (Iterator iter = students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[]) iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      }

注:hql不支持select * 的查询形式,但是Hibernate支持原生态的SQL语句,我们可以利用SQL语句进行查询,另外它类似于HQL的查询多个属性,所以返回的是一个对象数组类型的集合。

13.分页查询
 
      List students = session.createQuery("from Student") 
     .setFirstResult(1) 
     .setMaxResults(2) 
     .list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Student student = (Student)iter.next(); 
 System.out.println(student.getName()); 
      } 
14.导航查询
 
      List students = session.createQuery("from Student s where s.classes.name like '%2%'") 
     .list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Student student = (Student)iter.next(); 
 System.out.println(student.getName()); 
      }

注:上述查询语句中的s.classes.name是从学生导航到班级classes在获取班级的名称name。也可以反过来导航:从班级导航到学生在得到某个属性。另外程序中查询语句的意思是要查询班级名称中含有2的所有学生。

15.内连接查询
 
    List students = session.createQuery("select c.name, s.name from Student s join s.classes c") 
   .list(); 
     
    for (Iterator iter=students.iterator(); iter.hasNext();) { 
      Object[] obj = (Object[])iter.next(); 
      System.out.println(obj[0] + ", " + obj[1]); 
    } 

注:内连接关键字为join,另外还是用了别名和导航进行连接。上述查询语句的意思为:从学生表和班级表中查询中班级名称和学生名称(内连接是查询出必须有值得属性,比如没有班级没有学生或者学生没有班级是查询不出来的)。

16.左连接
 
      List students = session.createQuery("select c.name, s.name from Student s left join s.classes c") 
     .list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[])iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      }

注:使用左连接的关键字为left join。上述查询语句的意思为:从学生和班级表中,查询出班级名称和学生名称,因为是左连接,所以没有班级的学生也会被查询出来。

17.右连接
[java] view plain copy
 
      List students = session.createQuery("select c.name, s.name from Student s right join s.classes c") 
     .list(); 
       
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
 Object[] obj = (Object[])iter.next(); 
 System.out.println(obj[0] + ", " + obj[1]); 
      }

注:使用右连接的关键字为right join。上述查询语句的意思为:从学生和班级表中,查询出班级名称和学生名称,因为是右连接,所以没有学生的班级会被查询出来。

18.统计查询
Long count = (Long)session.createQuery("select count(*) from Student").uniqueResult();

注:hql中唯有统计查询才可以带*号。uniqueResult()表示只有一条结果集,返回的是Long类型。

19.复合查询
 
      String hql = "select c.name, count(s) from Classes c join c.students s group by c.name order by c.name"; 

      List students = session.createQuery(hql).list(); 
       
      for (int i=0; i

注:hql同样支持分组、排序等等。上述语句的意思是:查询每个班级的名称并且查询出每个班级的学生人数,按班级名称分组,按班级名称排序

总结

以上就是本文关于Hibernate hql查询代码实例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/141709.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号