什么是HQL?
HQL是Hibernate Query Language的缩写,提供更加丰富灵活、更为强大的查询能力;HQL更接近SQL语句查询语法。
HQL与SQL有何不同:
1.HQL
对查询条件进行了面向对象封装,符合编程人员的思维方式,格式:from + 类名 + 类对象 + where + 对象的属性
区分大小写,关键字不区分大小写
从下标0开始计算位置(hibernate5之后不支持)
支持命名参数
2.SQL
sql是面向数据库表查询,格式:from + 表名 + where + 表中字段
不区分大小写
从顺序1开始计算位置
不支持:命名参数
处理返回的结果集
单个对象
多个列段
object【】
对象(多个列段、全部)
Map
这里写了一个JUnit测试类来测试这些效果
注意:测试类中需要设置session,transaction属性,然后就可以在类中写方法论
1. 单个对象
select没有逗号
如果是单个列段的话,就直接可以用String接收对象,这样就避免一些麻烦
/
返回单个列段,用字符串就可以接受
/
@Test
public void testList2() {
Query query = session.createQuery("select b.bookName as ss from Book b");
List list = query.list();
for (String b : list) {
System.out.println(b);
}
}
效果:
2.1 Object【】
b.bookId, b.bookName...
如果有两个或者两个以上的列段可以用数组来接收
/
查两个列段及以上,默认返回的是Object【】
/
@Test
public void testList3() {
Query query = session.createQuery("select b.bookId,b.bookName as ss from Book b");
List list = query.list();
for (Object【】 b : list) {
System.out.println(Arrays.toString(b));
}
}
效果:
2.2 book对象
其实两个以上也可以用对象来接收
/
查两个列段及以上,也可返回对象,前提是有对应的构造函数
/
@Test
public void testList5() {
Query query = session.createQuery("select new Book(b.bookId,b.bookName) from Book b");
List list = query.list();
for (Book b : list) {
System.out.println(b);
}
}
效果:
2.2.1 也是用对象来接收
/
返回对象(多个)
/
@Test
public void testList1() {
Query query = session.createQuery("from Book");
List list = query.list();
for (Book b : list) {
System.out.println(b);
}
}
效果:
3.Map
new Map(b.bookId as bid, b.bookName as bname)
/
注意map是函数,所以不区分大小写,返回的是map集合
/
@Test
public void testList4() {
Query query = session.createQuery("select new mAp(b.bookId,b.bookName) from Book b");
List list = query.list();
for (Map b : list) {
System.out.println(b);
}
}
效果:
HQL中使用占位符
占位符从下标0开始计算位置
hibernate5之后不再支持占位符
命名参数的使用
/
HQL语句支持占位符
/
@Test
public void testList6() {
// Query query = session.createQuery("from Book where bookId = :bookId");
// query.setParameter("bookId", 1);
// Book b = (Book) query.getSingleResult();
// System.out.println(b);
Query query = session.createQuery("from Book where bookId in (:bookIds)");
query.setParameterList("bookIds", new Integer【】 {1,2,4});
// List params = new ArrayList();
// params.add(1);
// params.add(2);
// params.add(4);
// query.setParameterList("bookIds", params);
List list = query.list();
for (Book b : list) {
System.out.println(b);
}
}
//代码效果参考:http://www.jhylw.com.cn/550425681.html命名参数的用法就是:
Query query = session.createQuery("from Book where bookId in (:bookIds)");
query.setParameterList("bookIds", new Integer【】 {1,2,4});
连接查询
/
HQL支持连接查询
/
@Test
public void testList7() {
Query query = session.createQuery("select o.orderNo,oi.quantity from Order o,OrderItem oi where o = oi.order");
List list = query.list();
for (Object【】 b : list) {
System.out.println(Arrays.toString(b));
}
}
聚合函数
sum 总计
avg 平均值
max 最大
min 最小
count 总数
/
HQL支持聚合函数
/
@Test
public void testList8() {
Query query = session.createQuery("select count() from Book");
Long singleResult = (Long) query.getSingleResult();
System.out.println(singleResult);
}
HQL分页
/**
HQL分页
/
@Test
public void testList9() {
Query query = session.createQuery("from Book");
query.setFirstResult(2);
query.setMaxResults(3);
List list = query.list();
for (Book b : list) {
System.out.println(b);
}
}
使用HQL实现通用查询
BaseDao类
这就是通用的实体查询类
package com.ht.five.Dao;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.hibernate.Query;
import org.hibernate.Session;
import com.ht.five.Util.PageBean;
/**
通用查询类
@author Administrator
/
public class BaseDao {
/**
@param map 将要设置的阐述用Map的形式来传递
@param query 查询对象
/
public void setParam(Map map, Query query) {
if(map != null && map.size() > 0) {
Object value = null;
Set
for (Entry entry : entries) {
value = entry.getValue();
//判断类型,根据类型来设置命名参数的值
if(value instanceof Object【】) {
query.setParameterList(entry.getKey(), (Object【】)value);
}else if(value instanceof Collection) {
query.setParameterList(entry.getKey(), (Collection)value);
}else {
query.setParameter(entry.getKey(), value);
}
}
}
}
/
传入hql语句 ,返回该语句所查到的总行数
@param hql
@return
/
public String getCountHql(String hql) {
/
下面这种做法的原因是请看这两条hql语句:
from Book
select from Book
所有要想使这个方法同意就是将from这个位置做截断拼接
/
//获取到FROM的位置
int index = hql.toUpperCase().indexOf("FROM");
//直接从FROM截断,将select count() 拼接上就ok了
return "select count()" + hql.substring(index);
}
/**
通用查询方法
@param session
@param map
@param hql
@param pageBean
@return
/
public List executeQuery(Session session, Map map, String hql, PageBean pageBean) {
List list = null;
if(pageBean != null && pageBean.isPagination()) {
//获取该查询的总行数
String countHql = getCountHql(hql);
Query countQuery = session.createQuery(countHql);
//给预定于的hql语句的命名参数赋值
this.setParam(map, countQuery);
//将总行数放入PageBean对象
pageBean.setTotal(countQuery.getSingleResult().toString());
Query query = session.createQuery(hql);
//给预定于的hql语句的命名参数赋值
this.setParam(map, query);
//设置开始位置(下标从0开始)
query.setFirstResult(pageBean.getStartIndex());
//这是偏移量,就是一页展示几条数据
query.setMaxResults(pageBean.getRows());
list = query.list();
}
else {
//如果不分页 直接查
Query query = session.createQuery(hql);
this.setParam(map, query);
list = query.list();
}
return list;
}
}
BookDao类<button class="c