hql

HQL

是Hibernate Query Language的缩写

hql 与 sql 的区别/异同

hql sql
类名/属性 表名/列名
区分大小写,关键字不区分大小写 不区分大小写
别名 : ?,从下标0开始计算位置(hibernate5之后不支持) 别名:?,从顺序1开始计算位置
:命名参数 不支持:命名参数
面向对象的查询语言 面向结构查询语言

hql 语句介绍

package com.hyf.xFive.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.hyf.four.entity.Book;
import com.hyf.two.util.SessionFactoryUtils;

public class HqlTest {
	private Session session;
	private Transaction transaction;
	
	@Before
	public void before() {
		session = SessionFactoryUtils.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void after() {
		transaction.commit();
		session.close();
	}
	
	/**
	 * 返回对象(多个)
	 */
	@Test
	public void testList1() {
		Query query = session.createQuery("from Book");
		List<Book> list = query.list();
		for (Book b : list) {
			System.out.println(b);
		}
	}
	
	/**
	 * 返回单个列段,用字符串就可以接受
	 */
	@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);
		}
	}
	
	/**
	 * 查两个列段及以上,默认返回的是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));
		}
	}
	
	/**
	 * 注意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);
		}
	}
	
	/**
	 * 查两个列段及以上,也可返回对象,前提是有对应的构造函数
	 */
	@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);
		}
	}
	
	/**
	 * 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)");
		// 查询id 为 1 , 2,4
		// 传数组
//		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);
		}
	}
	
	/**
	 * HQL支持连接查询
	 */
	@Test
	public void testList7() {
		Query query = session.createQuery("select o.orderNo,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));
		}
	}
	
	/**
	 * HQL支持聚合函数
	 */
	@Test
	public void testList8() {
		Query query = session.createQuery("select count(*) from Book");
		Long singleResult = (Long) query.getSingleResult();
		System.out.println(singleResult);
	}
	
	/**
	 * HQL分页
	 */
	@Test
	public void testList9() {
		Query query = session.createQuery("from Book");
		query.setFirstResult(2);
		query.setMaxResults(3);
		List<Book> list = query.list();
		for (Book b : list) {
			System.out.println(b);
		}
	}
}

query.list(); 查询多条数据
query.getSingleResult() 查询多条数据单条

在这里插入图片描述

通用查询hql baseDao

版本一

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 );
		
		// 当 bname 不等于空的时候赋值
		if(StringUtils.isNotBlank(bname)) {
			query.setParameter("bookName", bname);
		}
		
		// 分页
		if(pageBean !=null && pageBean.isPagination()) {
			// 设置pageBean 起始下标
			query.setFirstResult(pageBean.getStartIndex());
			query.setMaxResults(pageBean.getRows());
		}
		List list = query.list();
		
		return list;
	}
	

问题:每增加一个查询就需要写一个这种语句,如果数量过多的话,导致重复代码过多。
在这里插入图片描述

版本二
通用 beasDao

package com.hyf.xFive.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、分页(可以简化)
 *       
 *      基于sql的分页的查询的做法
 *         1、首先要查询出符合条件的总记录数
 *         2、返回符合条件的记录
 *      参数:sql ,pageBean,Class clz
 *       1、 countSql = select count(*) from (sql) t;
 *       2、 pageSql = sql + " limit " +start +" , " +rows
 *       
 *      基于hql的分页的查询的做法
 *        hql =          from Book where bookName like "%xxx%"
 *        hql = select * from Book where bookName like "%圣墟%"
 *        1、countHql = select count(*) hql  
 *        
 *          
 * @author 17628
 *
 */
public class BeasDao {

	/**
	 * @param query  里面包含了带有参数的hql 语句,需要等待赋值
	 *       "from Book where 1=1  and bookName like :bookName
	 * @param map  
	 *        =request.getParameterMap();
	 */      
	public void setParam(Query query, Map<String, Object> paramMap) {
         if(paramMap !=null && paramMap.size()!=0) {
        	  // 遍历 paramMap 集合 得到前台传来的数据
        	 Set<Entry<String, Object>> entrySet = paramMap.entrySet();
        	 for (Entry<String, Object> entry : entrySet) {
			  // 遍历之后,给 query 赋值
        		 String key = entry.getKey();
        		 Object value = entry.getValue();
        		 // 我们这里要考虑以下 传过来的是数组 还是集合
        		 if(value instanceof Object[]) {
        			 // 当 value 为数组时
        			 query.setParameter(key, (Object [])value);
        		 }else if(value instanceof Collection){
        			// 当 value 为集合时
        			 query.setParameter(key, (Collection)value);
        		 }else {
        			 // 普通字符串
        			 query.setParameter(key, value);
        		 }
			}
         }
	}
	
	
	/**
	 *  拼装符合条件的总记录数
	 * 2、countHql = select count(*) hql  
	 *   hql 可以能为以下两种情况
	 *       hql =          from Book where bookName like "%xxx%"
 *           hql = select * from Book where bookName like "%圣墟%"
	 *       所以通过截取得到  from和后面的条件
	 * 
	 * @param hql
	 * @return
	 */
	public String getCountSql(String hql) {
		// toUpperCase()  转大写  。因为hql 区分大小写 ,我们干脆把hql语句转成 大写
		// indexOf()      取 FROM 的下标
		int fromIndex = hql.toUpperCase().indexOf("FROM");
		return "select count(*)"+hql.substring(fromIndex);
	}
	
	
	/**
	 * 基于hql通用查询方法
	 * 
	 * @param hql       最终传来的 hql 语句
	 * @param pageBean  分页
	 * @param paramMap  =request.getParameterMap(); 前台传来的 值
	 * @param session   创建 Query 对象
	 * @return
	 */
	public List  executeQuery(String hql,PageBean pageBean,Map<String,Object> paramMap,Session session) {
		List list = null;
		Query query = null;
		if(pageBean != null && pageBean.isPagination()) {
			// 获取查询的总数量
			String countHql =getCountSql(hql);
			Query createQuery = session.createQuery(countHql);
			this.setParam(createQuery, paramMap);
			//将总行数放入PageBean对象
			pageBean.setTotal(createQuery.getSingleResult().toString());
			
			// 返回符合条件的记录
			query = session.createQuery(hql);
			//给预定于的hql语句的命名参数赋值。有多少赋多少
			this.setParam(query, paramMap);
			//设置开始位置(下标从0开始)
			query.setFirstResult(pageBean.getStartIndex());
			//这是偏移量,就是一页展示几条数据
			query.setMaxResults(pageBean.getRows());
			list=query.list();
		}else {
			// 不分页
			query=session.createQuery(hql);
			this.setParam(query, paramMap);
			list=query.list();
		}
		return list;
		
	}
}

BookDao
它需要继承 BaseDao

public  List<Book> listPlus(Book book,PageBean pageBean){
		Session session = SessionFactoryUtils.openSession();
		String hql = "from Book where 1=1";
		String bname = book.getBookName();
		
//		这个是jsp 自动传递过来的,不与要手写,模拟一下
		Map<String, Object> map = new HashMap<String, Object>();
		
		if(StringUtils.isNotBlank(bname)) {
			hql +=" and bookName like :bookName";
			map.put("bookName", bname);
		}
		
		List list = super.executeQuery(hql, pageBean, map, session);
		session.close();
		return list;
	}

JUnit 测试

	@Test
	public void testList11() {
        Book b = new Book();
        PageBean pageBena = new PageBean();
        pageBena.setPage(3);
     //   b.setBookName("%圣墟%");
        List<Book> list = this.bookDao.listPlus(b, pageBena);
        for (Book book : list) {
			System.out.println(book);
		}
	}

测试结果:
在这里插入图片描述

发布了73 篇原创文章 · 获赞 6 · 访问量 2391
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览