HQL(Hibernate Query Language) 是面向对象的查询语言, 它和 SQL 查询语言有些相似. 在 Hibernate 提供的各种检索方式中, HQL 是使用最广的一种检索方式.。它有如下功能:
在查询语句中设定各种查询条件;
支持投影查询, 即仅检索出对象的部分属性;
支持分页查询;
支持连接查询;
支持分组查询, 允许使用 HAVING 和 GROUP BY 关键字;
提供内置聚集函数, 如 sum(), min() 和 max();
支持子查询;
支持动态绑定参数;
能够调用 用户定义的 SQL 函数或标准的 SQL 函数。
HQL 查询包括以下步骤:
获取Hibernate Session对象。
编写HQL语句
以HQL语句作为参数,调用Session的createQuery方法创建查询对象。
如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值。
调用Query对象的list()或uniqueResult()方法返回查询结果列表(持久化实体集)
HQL查询实例:
private Session session;
private Transaction transaction;
@Before
public void before() {
session = SessionFactoryUtil.getSession();
transaction = session.beginTransaction();
}
@After
public void after() {
transaction.commit();
SessionFactoryUtil.closeSession();
}
/**
* 情况一:结果返回对象(用该对象的集合接收)
@Test
public void test1() {
String hql="from Book";//Book是实体类名
Query query = session.createQuery(hql);
List<Book> list = query.list();
for (Book book : list) {
System.out.println(book);
}
}
查询结果:
/**
* 情况二:查数据库表中的一列(用该列的数据类型的集合接收)
* 数据库:在数据库表中查询,是不区分大小写
* hql:由于你查询的是实体类的属性,那么就区分大小写了
*/
@Test
public void test2() {
String hql="select bookName from Book";//bookName是实体类里的属性名
Query query = session.createQuery(hql);
List<String> list = query.list();
for (String string : list) {
System.out.println(string);
}
}
查询结果:
/**
* 情况三:查数据库表中的多列(用object数组集合接收,但推荐用List<Map>接收)
*/
@Test
public void test3() {
String hql="select bookName,bookId from Book";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
for (Object[] obj : list) {
System.out.println(Arrays.toString(obj));
}
}
查询结果:
/**
* 情况四:通过hibernate函数Map去处理(用List<Map>接收)
* 函数这个词是源自于数据库
* 函数不区分大小写
*/
@Test
public void test4() {
String hql="select new map(bookName,bookId) from Book";
Query query = session.createQuery(hql);
List<Map> list = query.list();
for (Map obj : list) {
System.out.println(obj);
}
}
查询结果:
/**
* 情况五:通过构造方法进行查询(前提是该实体类里必须要有该构造方法,否则会报错)
*/
@Test
public void test5() {
String hql="select new Book(bookId,bookName) from Book";
Query query = session.createQuery(hql);
List<Book> list = query.list();
for (Book obj : list) {
System.out.println(obj);
}
}
查询结果:
/**
* hibernate中的占位符问题
* hibernate5版本以后弃用“?”
*/
@Test
public void test6() {
String hql="from Book where bookId = :id";
Query query = session.createQuery(hql);
query.setParameter("id", 3);//用占位符传一个参数,查询ID为3的书籍
Book book = (Book) query.getSingleResult();
System.out.println(book);
}
查询结果:
/**
* 用占位符传多个参数(查ID为1和3的书籍)
*/
@Test
public void test7() {
String hql="from Book where bookId in (:ids)";
Query query = session.createQuery(hql);
/*
* 写法一
*/
// query.setParameterList(“ids”, new Integer[] {1,3});
List ids=new ArrayList();
ids.add(1);
ids.add(3);
/*
* 写法二
*/
query.setParameterList(“ids”, ids);
List list = query.list();
for (Book book : list) {
System.out.println(book);
}
}
查询结果:
/**
* 联表查询(查订单和订单项)
*/
@Test
public void test8() {
//写法一
// String hql=“select o.orderNo,oi.productId from Order o,OrderItem oi where o.orderId=oi.order.orderId”;
//写法二
String hql=“select new map(o.orderNo,oi.productId) from Order o,OrderItem oi where o=oi.order”;
Query query = session.createQuery(hql);
List
/**
* 聚合函数(查书籍价格的平均数)
*/
@Test
public void test9() {
String hql="select avg(price) from Book";
Object singleResult = session.createQuery(hql).getSingleResult();
System.out.println(singleResult);
}
查询结果:
/**
* 分页
*/
@Test
public void test10() {
String hql="from Book";
Query query = session.createQuery(hql);
int page=2;//查第二页的数据
int ofset=2;//每页显示2条数据
query.setFirstResult((page-1)*ofset);//设置起始记录下标
query.setMaxResults(ofset);//设置返回的最大结果集
List<Book> list = query.list();
for (Book book : list) {
System.out.println(book);
}
}
查询结果:
总结:HQL vs SQL
HQL 查询语句是面向对象的, Hibernate 负责解析 HQL 查询语句, 然后根据对象-关系映射文件中的映射信息, 把 HQL 查询语句翻译成相应的 SQL 语句。HQL 查询语句中的主体是域模型中的类及类的属性。
SQL 查询语句是与关系数据库绑定在一起的。SQL 查询语句中的主体是数据库表及表的字段。