Hiberate的HQL之通用分页方法

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

输出结果:
在这里插入图片描述


版权声明:本文为weixin_45092850原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。