本文主要是介绍Hibernate的HQL简单查询语句,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
不管数据库用的是什么类型,对于查询语句来说,我们总是习惯了SQL语句。它之所以能够屹立不倒,一方面已成为了习惯,一方面确实功能强大。Hibernate相对于其他ORM实现来说,数据查询是它独特的亮点。它所提供的HQL,类似于SQL语句,但是却比SQL语句灵活。它跟SQL语句有很多相似的地方,是因为这样的话更容易被接受。
HQL查询
简单属性查询
简单属性就是一个实体本身的属性,不包括它和其他实体的关联属性。在查询简单属性时,HQL语句和SQL语句类似,可以查询一个字段,也可以查询多个字段。因为Hibernate是面向对象操作的,所以也就是可以查询单一属性,也可以查询多个属性。
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]);
}
多个属性查询时,也可以返回实体集合,只需要对HQL语句稍加改动即可:
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());
}
3、使用别名
在SQL语句中,经常用到连接的SQL语句用别名比较方便,在HQL语句中同样也可以用别名,和不用别名的查询效果是一样的。
List students = session.createQuery("select s.id, s.name from Student s").list();
实体对象查询
实体对象查询时,相当于查询整张表的数据,返回实体对象集合,这个和SQL语句结合起来很容易理解。关键就在于,使用实体对象查询时,是采用的list方法,还是iterate方法,这两个方法有很大的区别。
使用list方法时,Hibernate会发出一条SQL语句,查询该实体对应表的所有数据。但是使用iterate方法时,Hibernate会首先发出一条查询所有id的SQL语句,然后用每一个id为条件查询单个数据,这是就会发出N+1条SQL语句。
/*** 采用list查询实体对象会发出一条查询语句,取得实体对象数据* * Hibernate: select student0_.id as id0_, student0_.name as name0_, * student0_.createTime as createTime0_, student0_.classesid as classesid0_ * from t_student student0_*/
List students = session.createQuery("from Student").list();
for (Iterator iter=students.iterator(); iter.hasNext();) {Student student = (Student)iter.next();System.out.println(student.getName());
}
/*** 会出现N+1问题,所谓的N+1指的是发出了N+1条sql语句* * 1:发出一条查询id列表的语句* Hibernate: select student0_.id as col_0_0_ from t_student student0_* * N:根据id发出N条sql语句,加载相关的对象* Hibernate: select student0_.id as id0_0_, student0_.name as name0_0_, * student0_.createTime as createTime0_0_, student0_.classesid as classesid0_0_ * from t_student student0_ where student0_.id=?* */
Iterator iter = session.createQuery("from Student").iterate();
while (iter.hasNext()) {Student student = (Student)iter.next();System.out.println(student.getName());
}
解决N+1问题,可以采用Hibernate的缓存,先使用list方法将数据查询出来,然后数据会自动被放到一级缓存中,再用iterate方法查询时,会直接从缓存中查询,就不会发出SQL语句了,其实就是曲线救国。
条件查询
用条件查询时,查询条件可以采用拼接字符串的形式,也可以用?来代替,同样也可以传递一个参数集合。同样,在HQL语句中,也可以使用数据库函数。
//拼接字符串
List students = session.createQuery("select s.id, s.name from Student s where s.name like '%0%'").list();
//可以使用?方式传递参数
List students = session.createQuery("select s.id, s.name from Student s where s.name like ?").setParameter(0, "%0%").list();
//可以采用 :参数名 的方式传递参数
List students = session.createQuery("select s.id, s.name from Student s where s.name like :myname").setParameter("myname", "%0%").list();
//采用 ?方式,查询学号为1,2,3,4,5的学生
List students = session.createQuery("select s.id, s.name from Student s where s.id in(?, ?, ?, ?, ?)").setParameter(0, 1).setParameter(1, 2).setParameter(2, 3).setParameter(3, 4).setParameter(4, 5).list();
//查询2009-08的学生,可以调用mysql的日期格式化函数
List students = session.createQuery("select s.id, s.name from Student s where date_format(s.createTime, '%Y-%m')=?").setParameter(0, "2009-08").list();
插入SQL语句
HQL语句不光自己可以查询,也可以直接用插入SQL语句查询,利用SQL语句中的函数进行查询。
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();
总结
HQL语句的关键字不区分大小写,不过习惯上都是用的小写。因为Hibernate是面向对象的,所以HQL语句中,查询时并不使用数据库表名,而是使用实体类名,所以上面看到的HQL语句中,Student一定要跟实体类名相同,这样通过映射文件配置的实体类和表的映射,才可以找到数据库中的表。通常习惯使用SQL语句后,那么和它规则类似的查询语句也比较容易接受,这也是为什么HQL语句比SQL语句灵活,但是却跟SQL语句很相似的原因。
这篇关于Hibernate的HQL简单查询语句的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!