本文讲解Hibernate常用的HQL查询语言。
1、简述
HQL语言(Hibernate Query Language)类似于SQL语言,有SQL语言很多关键字,如select、from、where、count()、order by等等,但是hql是一种面向对象的语言,能够直接使用实体类及其属性。
2、大小写不敏感
HQL语言对大小写不敏感,但是涉及到java的类名、包名、属性名等时时大小写敏感的。需要注意。如果实体类是唯一的可以省略包名,但是如果有两个及其以上的实体类时,需要带上包名,否则hibernate无法知道是哪个实体类。
eg:
select d from com.arvinfe.hibernate.bean.Dog d;
3、HQL查询
(1)、查询单个对象
Query q = session.createQuery("select count(c) from Cat c");unque返回单个对象,使用unique获取返回值时,查询结果只能有一个,否则会抛出异常。该方法可以用来查询记录条数。
Number num = (Number)q.uniqueResult();
int count = num.intValue();
(2)、返回集合属性
eg:
List<Cat> catList1 = session.createQuery("select c from Cat c").list();
List<String> nameList = session.createQuery("select c.name from Cat c").list();
List<String[]> nameLists = session.createQuery("select c.name,c.mother.name from Cat c").list();
List<Cat> catLists = session.createQuery("select c.mother from Cat c").list();
list()可以返回尸体对象,也可以返回实体对象的某属性或者某些属性。
(3)、返回Object[]集合
eg:
List<Object[]> list = session.createQuery("select c.name,c.mother,c.createDate from Cat c").list();查询多个属性时,hibernate将同时返回多个对象到List<Object[]>中,如果只是查询一个属性,则不会返回数组而是直接返回该类型的数据。
for(Object[] row : list) {
for(Object obj : row) {
System.out.println("obj is " + obj.toString());
}
}
eg:
select c.name from Cat c;将直接返回List<String>的集合。
(4)、返回List类型
eg:
List<List> list = session.createQuery("select new List(c.name,c.mother,c.createDate) from Cat c").list();
for(List row : list) {
for(Object obj : row) {
//do something.
}
}
(5)、返回Map类型
eg:
List listMap = session.createQuery("select new Map(c.name as name,c.mother as mother,c.createDate as createDate) from Cat c").list();
for(Map map : listMap) {
String name = map.get("name");
Cat mother = map.get("mother");
String createDate = map.get("createDate");
}
(6)、返回java实体对象
eg:
List<Cat> catList = session.createQuery("select new Cat(c.name,c.createDate) from Cat c").list();返还java实体对象时需要注意,实体类中需要有对应的构造函数。
(7)、条件查询
eg:
session.createQuery("select c from Cat c where c.mother.name = null and c.createDate < :createDate").setParameter("createDate",new Date).list();条件查询类似于sql。
(8)、跨表查询
eg:
List<Event> list = session.createQuery("select e from Event e where e.cat.name = 'Kitty'").list();
上述的语句将查询event表和cat表。
(9)、级联查询
HQL支持SQL的级联查询,如inner join、left join、right join、full join等。级联查询适用于集合属性,如Cat的events集合属性。Clazz的学生集合属性等。
eg:
List<Cat> bList = session.createQuery("select c from Cat c left join c.events e where e.description like :description").setParameter("description","%吃饭%").list();
4、统计函数
hibernate提供了一系列的统计函数,这些统计函数在使用时由hibernate转化成底层数据库支持的sql语句。
5、分页查询
web程序经常需要使用分页显示,hibernate提供了分页查询,分页显示一般是先查询就得总数,然后查询本页显示的记录。
eg:
Long count = (Long)session.createQuery("select count(c) from Cat c").uniqueResult();
List<Cat> list = session.createQuery("from Cat").setFirstResult(0).setMaxResults(10).list();
通过setFirstResult()设置分页的第一条记录,然后通过setMaxResults()设置取本页的数据数。查询总数时的返回值由实体类的主键类型决定,如果主键为short类型,则返回值可能为Integer类型。
6、使用普通SQL
eg:
SQLQuery sqlQuery = session.createSQLQuery("show variables");
List<Object[]> list = sqlQuery.list();
SQLQuery sqlQuery = session.createSQLQuery("select * from tb_cat");
sqlQuery.addEntity(Cat.class);
List<Cat> catList = sqlQuery.list();
7、命名常用的查询
(1)、配置命名查询
import javax.persistence.*;
@NamedQuery(name="all cat",query = "select c from Cat c")
@NamedNativeQuery(name="all cat",query = "select * from tb_cat")
@Entity
@Table(name="tb_cat")
public class Cat() {
//
}
@NameQuery用于配置命名的HQL查询;
@NameNativeQuery用于配置底层数据库的sql查询。