hibernate的HQL查询语言

时间:2022-09-22 09:45:52

本文讲解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)、查询单个对象


eg:

Query q = session.createQuery("select count(c) from Cat c");
Number num = (Number)q.uniqueResult();
int count = num.intValue();
unque返回单个对象,使用unique获取返回值时,查询结果只能有一个,否则会抛出异常。该方法可以用来查询记录条数。


(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();

for(Object[] row : list) {
for(Object obj : row) {
System.out.println("obj is " + obj.toString());
}
}
查询多个属性时,hibernate将同时返回多个对象到List<Object[]>中,如果只是查询一个属性,则不会返回数组而是直接返回该类型的数据。

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查询。