Hiberate之HQL
1. 什么是hql
HQL是Hibernate Query Language的缩写 (Hibernate查询语言)
2.那么 hql和sql有什么区别/异同?
HQL | SQL |
---|---|
类名/属性 | 表名/列名 |
区分大小写,关键字不区分大小写 | 不区分大小写 |
可以别名 | 可以别名 |
占位符?,从下标0开始计算位置(hibernate5之后不支持) | ?,从顺序1开始计算位置 |
传参 :命名参数 | 不支持:命名参数 |
面向对象的查询语言 | 面向结构查询语言 |
3. 关于HQL处理返回的结果集
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);
}
}
结果:
Book [bookId=1, bookName=西游记, price=50.0]
Book [bookId=2, bookName=红楼梦, price=50.0]
Book [bookId=3, bookName=水浒, price=50.0]
Book [bookId=4, bookName=三国演义, price=50.0]
Book [bookId=5, bookName=斗罗大陆, price=10.0]
Book [bookId=6, bookName=洞中强者, price=10.0]
3.2返回单个列段,用字符串就可以接收
@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);
}
}
结果:
西游记
红楼梦
水浒
三国演义
斗罗大陆
洞中强者
3.4集合(注意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);
}
}
结果:
{0=1, 1=西游记}
{0=2, 1=红楼梦}
{0=3, 1=水浒}
{0=4, 1=三国演义}
{0=5, 1=斗罗大陆}
{0=6, 1=洞中强者}
3.5构造方法(查两个列段及以上,也可返回对象,前提是有对应的构造函数)
@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);
}
}
结果:
查询两个字段,另一个没有查就是null
Book [bookId=1, bookName=西游记, price=null]
Book [bookId=2, bookName=红楼梦, price=null]
Book [bookId=3, bookName=水浒, price=null]
Book [bookId=4, bookName=三国演义, price=null]
Book [bookId=5, bookName=斗罗大陆, price=null]
Book [bookId=6, bookName=洞中强者, price=null]
6.聚合函数
Hql里面也是有聚合函数的如:sum, avg, max, min, count
这里就举一个例子:使用count
@Test
public void testList8() {
Query query = session.createQuery(“select count(*) from Book”);
//getSingleResult 是用来获取单条记录的
Long singleResult = (Long) query.getSingleResult();
System.out.println(singleResult);
}
结果为:6
HQL通用分页方法
先把它通用的BaseDao写出来
package com.tzp.five.util;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;import java.util.concurrent.ConcurrentLinkedQueue;
import org.hibernate.Session;
import org.hibernate.query.Query;
/**
* 1,设置参数的问题
* 2.分页代码重复的问题
* @author a
*
*sql的通用分分页的时候
*
*getCountSql(sql)
* hql=" from Book where bookName like :bookName"
* select count(1) hql
*/
public class BaseDao {
/**
*
* @param map 参数键值集合
* @param query 预定义处理的hql对象
*/
public void setParam(Map<String,Object> map,Query query) {
if(map!=null&&map.size()>0) {
Object value=null;
Set<Entry<String,Object>> entrySet=map.entrySet();
for (Entry<String, Object> entry : entrySet) {
//列子的圣墟,但是有时候它并不是单纯的字符串。可能是数组比如爱好,也可能是集合
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);
}
}
}
}
public String getCountHsql(String hql) {
int index = hql.toUpperCase().indexOf("FROM");
return "select count(*) "+hql.substring(index);
}
/**
* 通用查询方法
* @param session
* @param map
* @param hql
* @param pageBean
* @return
*/
public List executeQuery(Session session,Map<String, Object> map,String hql,PageBean pageBean) {
List list=null;
if(pageBean !=null&&pageBean.isPagination()) {
String CountHql=getCountHsql(hql);
Query counQuery = session.createQuery(CountHql);
this.setParam(map, counQuery);
pageBean.setTotal(counQuery.getSingleResult().toString());
Query query = session.createQuery(hql);
// 给预定义hql语句执行对象中参数赋值,有多少赋多少
this.setParam(map, query);
query.setFirstResult(pageBean.getRows());
list=query.list();
}else {
Query query = session.createQuery(hql);
// 给预定义hql语句执行对象中参数赋值,有多少赋多少
this.setParam(map, query);
list=query.list();
}
return list;
}
}
接着就是BookDao,需要继承BaseDao,以使用它通用的分页的方法
public List<Book> list2(Book book,PageBean pagebean) {
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
String bookName = book.getBookName();
Map<String, Object> map = new HashMap<>();
String hql = "from Book where 1=1";
if(StringUtils.isNotBlank(bookName)) {
hql += " and bookName like :bookName";
map.put("bookName", bookName);
}
List<Book> list = super.executeQuery(session, map, hql, pagebean);
transaction.commit();
session.close();
return list;
}
下面来测试一下
@Test
public void testList2() {
Book book=new Book();
PageBean pageBean=new PageBean();
// 从第几条数据开始分页
pageBean.setPage(2);
// 是否要分页
// pageBean.setPagination(false);
// book.setBookName("%斗%");
List<Book> list=this.bookDao.list2(book, pageBean);
for (Book b : list) {
System.out.println(b);
}
}
输出结果: