1. 什么是hql
HQL是Hibernate Query Language的缩写
********************查询 ****语言
查全部
2. hql和sql区别/异同
HQL | SQL |
---|---|
类名/属性 | 表名/列名 |
区分大小写,关键字不区分大小写 | 不区分大小写 |
别名 | 别名 as a |
?,从下标0开始计算位置(hibernate5之后不支持) | ?,从顺序1开始计算位置 |
:命名参数 select * from book where bookname= : bookname | 不支持:命名参数 |
面向对象的查询语言 | 面向结构(数据库)查询语言 |
3. 处理返回的结果集
3.1 多个对象
/**
* 返回对象(多个)
*/
@Test
public void testList1() {
Query query = session.createQuery("from Book");
List<Book> list = query.list();
for (Book b : list) {
System.out.println(b);
}
}
3.2 多个对象(2)
new 构造方法(attr1,attr2)
new Book(b.bookId, b.price)
/**
* 查两个列段及以上,也可返回对象,前提是有对应的构造函数
*/
@Test
public void testList5() {
Query query = session.createQuery("select new Book(b.bookId,b.bookName) from Book b");
List<Book> list = query.list();
for (Book b : list) {
System.out.println(b);
}
}
3.1 和3.2都是返回多个对象,但是两个查询的不同:
3.1 查询所有
3.2 只查询某几个字段名,必须要有这几个字段的构造参数才行
3.3 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<Object[]> list = query.list();
for (Object[] b : list) {
System.out.println(Arrays.toString(b));
}
}
3.4 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<Map> list = query.list();
for (Map b : list) {
System.out.println(b);
}
}
3.3 Object [] 和 3.4 Map 都是查多个字段,但是 Map会有下标显示出来,这样更清楚一些
3.5 返回类型 String
查询单个列段
/**
* 返回单个列段,用字符串就可以接受
*/
@Test
public void testList2() {
Query query = session.createQuery("select b.bookName as ss from Book b");
List<String> list = query.list();
for (String b : list) {
System.out.println(b);
}
}
4.HQL的其他查询
4.1 HQL语句支持占位符
@Test
public void testList6() {
Query query = session.createQuery("from Book where bookId in (:bookIds)");
// query.setParameterList("bookIds", new Integer[] {1,2,4});
List<Integer> params = new ArrayList<Integer>();
params.add(1);
params.add(2);
params.add(4);
query.setParameterList("bookIds", params);
List<Book> list = query.list();
for (Book b : list) {
System.out.println(b);
}
}
4.2 HQL支持连接查询
@Test
public void testList7() {
Query query = session.createQuery("select o.order_no,oi.quantity from Order o,OrderItem oi where o = oi.order");
List<Object[]> list = query.list();
for (Object[] b : list) {
System.out.println(Arrays.toString(b));
}
}
4.3 HQL支持聚合函数
@Test
public void testList8() {
Query query = session.createQuery("select count(*) from Book");
Long singleResult = (Long) query.getSingleResult();
System.out.println(singleResult);
}
查询的总条数:22
4.4 HQL分页
4.4.1 分页(只能分页查询)
直接在HqlTest 类写一个测试方法即可
@Test
public void testList9() {
Query query = session.createQuery("from Book");
query.setFirstResult(2); //从第几条数据开始
query.setMaxResults(5); //每页多少条数据
List<Book> list = query.list();
for (Book b : list) {
System.out.println(b);
}
}
4.4.2 分页(分页模糊查询)
现在BookDao写一个 分页查询
/**
* 分页查询 1.动态的拼接hql语句 2.需要给拼接的hql语句的命名参数赋值(可简化) 3.分页 (可简化)
*
* @param book
* @param pageBean
* @return
*/
public List<Book> list(Book book, PageBean pageBean) {
Session session = SessionFactoryUtils.openSession();
String hql = "from Book where 1=1";
String bname = book.getBookName();
if (StringUtils.isNotBlank(bname)) {
hql += " and bookName like :bookName";
}
Query query = session.createQuery(hql);
if (StringUtils.isNotBlank(bname)) {
query.setParameter("bookName", bname);
}
if (pageBean != null && pageBean.isPagination()) {
query.setFirstResult(pageBean.getStartIndex());
query.setMaxResults(pageBean.getRows());
}
List list = query.list();
session.close();
return list;
}
然后去 HqlTest 测试
@Test
public void testList10() {
Book book=new Book();
book.setBookName("%圣墟%");
PageBean pageBean=new PageBean();
pageBean.setRows(6);
List<Book> list = bookDao.list(book, pageBean);
for (Book b: list) {
System.out.println(b);
}
}
4.4.3 分页(4.4.2的升级版 分页模糊查询)
现在BaseDao中写一个通用的查询分页的方法
package com.wr.five.util;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.query.Query;
/**
* 基于hql语句的通用查询工具类
* 1.需要给拼接的hql语句的命名参数赋值(可简化)
* 2.分页 (可简化)
*
* @author Administrator
*/
public class BaseDao {
/**
*
* @param query 里面包含了带有命名参数的hql语句,需要等待赋值 from Book where 1=1 and bookName
* like :bookName
* @param paramMap paramMap=request.getParameterMap();
*/
public void setParam(Query query, Map<String, Object> paramMap) {
if (paramMap != null && paramMap.size() > 0) {
Set<Entry<String, Object>> entrySet = paramMap.entrySet();
for (Entry<String, Object> entry : entrySet) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof Object[]) {// value可能是数组
query.setParameterList(key, (Object[]) value);
} else if (value instanceof Collection) {// value可能是集合
query.setParameterList(key, (Collection) value);
} else {// value可能是字符串
query.setParameter(key, value);
}
}
}
}
/**
* 拼接符合条件的总条数
* @param hql form book where bookName like "%圣墟%"
* @return select * form book where bookName like "%圣墟%"
* hql有可能有两种,所以都先截取成 form book where bookName like "%圣墟%"
* 然后在查询
*/
public String getCountHql(String hql) {
int fromIndex=hql.toUpperCase().indexOf("FROM");
return "select count(*)"+hql.substring(fromIndex);
}
/**
* 通用分页查询方法
* @param hql
* @param pageBean
* @param paMap
* @param session
* @return
*/
public List executeQuery(String hql,PageBean pageBean,Map<String,Object> paMap,Session session) {
Query query=null;
List list=null;
if(pageBean !=null && pageBean.isPagination()) {
//查出符合条件的总条数
String countHql=getCountHql(hql);
Query countQuery = session.createQuery(countHql);
this.setParam(countQuery, paMap);
pageBean.setTotal(countQuery.getSingleResult().toString());
//2.返回符合条件的记录
query=session.createQuery(hql);
this.setParam(query, paMap);
query.setFirstResult(pageBean.getStartIndex());
query.setMaxResults(pageBean.getRows());
list=query.list();
}else {
query=session.createQuery(hql);
this.setParam(query, paMap);
list=query.list();
}
return list;
}
}
然后在BookDao中继承BaseDao
/**
* 基于hql list的plus版本
*
* @param book
* @param pageBean
* @return
*/
public List<Book> listPuls(Book book, PageBean pageBean) {
Session session = SessionFactoryUtils.openSession();
// 这个是jsp自动传递过来的,不需要手写
Map<String, Object> map = new HashMap<String, Object>();
String hql = "from Book where 1=1";
String bname = book.getBookName();
if (StringUtils.isNotBlank(bname)) {
hql += " and bookName like :bookName";
map.put("bookName", bname);
}
// Query query = session.createQuery(hql);
List list = super.executeQuery(hql, pageBean, map, session);
session.close();
return list;
}
最后在HqlTest中测试
@Test
public void testList11() {
Book book=new Book();
// book.setBookName("%圣墟%");
PageBean pageBean=new PageBean();
pageBean.setRows(6);
List<Book> list = bookDao.listPuls(book, pageBean);
for (Book b: list) {
System.out.println(b);
}
}
hql 和 sql 的分页查询 差不多,只是不需要再多写个分页的查询语句,
直接用着两个即可:
query.setFirstResult(pageBean.getStartIndex()); //从第几条数据开始
query.setMaxResults(pageBean.getRows()); //每页多少条数据