Hibernate之HQL

1. 什么是hql
HQL是Hibernate Query Language的缩写

2. hql和sql区别/异同

HQL                                                                           SQL

类名/属性                                                                   表名/列名

区分大小写,关键字不区分大小写                               不区分大小写

别名                                                                           别名

?,从下标0开始计算位置(hibernate5之后不支持)     ?,从顺序1开始计算位置

:命名参数                                                                   不支持:命名参数

面向对象的查询语言                                                   面向结构查询语言

基本功能演示:

package com.chenjiahao.five.test;

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.chenjiahao.four.entity.Book;
import com.chenjiahao.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【】
	 * b.bookId, b.bookName
	 */
	@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集合
	 *  new Map(b.bookId as bid, b.bookName as bname)
	 */
	@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);
		}
	}

	/**
	 * 查两个列段及以上,也可返回对象,前提是有对应的构造函数
	 *  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);
		}
	}

	/**
	 * HQL语句支持占位符
	 *    ?占位符
	 *    从下标0开始计算位置
     *    hibernate5之后不再支持?占位符(会出现sql攻击)
	 *    sql攻击比如:
	 *    select * from xxx where bid=?
	 *    pst.setString(1,"1 and name="zs"")
	 */
	@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);
		//:bookIds==:命名参数
		//数组
		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);
		}
	}

	/**
	 * HQL支持连接查询
	 */
	@Test
	public void testList7() {
		//以前的写法是:select * from t_hibername_order o,t_hibernate_order_item oi where o.order_id=oi.oid
		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() {
		//  还支持sum avg  max min
		Query query = session.createQuery("select count(*) from Book");
		//getSingleResult是用来获取单条记录的
		Long singleResult = (Long) query.getSingleResult();
		System.out.println(singleResult);
	}

	/**
	 * HQL分页
	 *
	 * sql:
	 * sql limit 起始位置,结束
	 *
	 * hql:
	 * 同样的可以自动根据数据库方言生成分页语句
	 *        setFirstResult:设置起始下标
	 *        setMaxResults:设置偏移量
	 *  mysql:hql limit 起始位置,结束
	 *  oracle : select * from (select t.*,rownum rn hql t where t.rn>5)t1 where t1.rn < 10
	 *
	 */
	@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);
		}
	}
}

  HQL通用分页查询:

工具类:PageBean(分页的实体类)

package com.chenjiahao.five.util;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

/**
 * 分页工具类
 *
 */
public class PageBean {

	private int page = 1;// 页码

	private int rows = 3;// 页大小

	private int total = 0;// 总记录数

	private boolean pagination = true;// 是否分页
	// 获取前台向后台提交的所有参数
	private Map<String, String[]> parameterMap;
	// 获取上一次访问后台的url
	private String url;

	/**
	 * 初始化pagebean
	 *
	 * @param req
	 */
	public void setRequest(HttpServletRequest req) {
		this.setPage(req.getParameter("page"));
		this.setRows(req.getParameter("rows"));
		// 只有jsp页面上填写pagination=false才是不分页
		this.setPagination(!"fasle".equals(req.getParameter("pagination")));
		this.setParameterMap(req.getParameterMap());
		this.setUrl(req.getRequestURL().toString());
	}

	public int getMaxPage() {
		return this.total % this.rows == 0 ? this.total / this.rows : this.total / this.rows + 1;
	}

	public int nextPage() {
		return this.page < this.getMaxPage() ? this.page + 1 : this.getMaxPage();
	}

	public int previousPage() {
		return this.page > 1 ? this.page - 1 : 1;
	}

	public PageBean() {
		super();
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public void setPage(String page) {
		this.page = StringUtils.isBlank(page) ? this.page : Integer.valueOf(page);
	}

	public int getRows() {
		return rows;
	}

	public void setRows(int rows) {
		this.rows = rows;
	}

	public void setRows(String rows) {
		this.rows = StringUtils.isBlank(rows) ? this.rows : Integer.valueOf(rows);
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}

	public void setTotal(String total) {
		this.total = Integer.parseInt(total);
	}

	public boolean isPagination() {
		return pagination;
	}

	public void setPagination(boolean pagination) {
		this.pagination = pagination;
	}

	public Map<String, String[]> getParameterMap() {
		return parameterMap;
	}

	public void setParameterMap(Map<String, String[]> parameterMap) {
		this.parameterMap = parameterMap;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	/**
	 * 获得起始记录的下标
	 *
	 * @return
	 */
	public int getStartIndex() {
		return (this.page - 1) * this.rows;
	}

	@Override
	public String toString() {
		return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination
				+ ", parameterMap=" + parameterMap + ", url=" + url + "]";
	}

}

 工具类:StringUtils:

package com.chenjiahao.five.util;

public class StringUtils {
	// 私有的构造方法,保护此类不能在外部实例化
	private StringUtils() {
	}

	/**
	 * 如果字符串等于null或去空格后等于"",则返回true,否则返回false
	 *
	 * @param s
	 * @return
	 */
	public static boolean isBlank(String s) {
		boolean b = false;
		if (null == s || s.trim().equals("")) {
			b = true;
		}
		return b;
	}

	/**
	 * 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false
	 *
	 * @param s
	 * @return
	 */
	public static boolean isNotBlank(String s) {
		return !isBlank(s);
	}

}

  BaseDao:

package com.chenjiahao.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;

/**
 * 1.设置参数问题
 * 2.分页代码重复的问题
 *
 * getCountSql(sql)
 * select count(1) from (sql) t
 *
 * getCountHql(hql)
 * hql = " from Book where bookName like :bookName"
 * hql ="select * from new Book(bid,bookName) where bookName like :bookName"
 *
 * @author dell
 *
 */
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 getCountHql(String hql) {
        	 // hql = " from Book where bookName like :bookName"
        		//	  hql ="select * from new Book(bid,bookName) where bookName like :bookName"
        	 //截取from后面的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 = getCountHql(hql);
        		 Query createQuery = session.createQuery(countHql);
        		 this.setParam(map, createQuery);
        		 pageBean.setTotal(createQuery.getSingleResult().toString());
        		 Query query = session.createQuery(hql);
        		 //给预定hql语句执行对象中的参数赋值,有多少赋值多少
        		 this.setParam(map, query);
        		 // 设置分页起始记录下标
        		 query.setFirstResult(pageBean.getStartIndex());
        		 //设置分页返回的最大结果集
        		 query.setMaxResults(pageBean.getRows());
        		 list=query.list() ;

        	 }else {
        		 Query query = session.createQuery(hql);
        		 //给预定hql语句执行对象中的参数赋值,有多少赋值多少
        		 this.setParam(map, query);
        		 list=query.list();
        	 }

        	 return list;
         }

}

  BookDao:

Bookdao继承Basedao

package com.chenjiahao.four.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;

import com.chenjiahao.five.util.BaseDao;
import com.chenjiahao.five.util.PageBean;
import com.chenjiahao.five.util.StringUtils;
import com.chenjiahao.four.entity.Book;
import com.chenjiahao.four.entity.Category;
import com.chenjiahao.two.util.SessionFactoryUtils;

public class BookDao extends 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);
		}
	}

  

原文地址:https://www.cnblogs.com/chenjiahao9527/p/11209315.html

时间: 2024-08-30 05:20:44

Hibernate之HQL的相关文章

Hibernate之HQL介绍

Hibernate中提供了多种检索对象的方式,主要包括以下种类: 导航对象图检索方式:根据已经加载的对象导航到其他对象 OID检索方式:根据对象的OID来检索对象 HQL检索方式:使用面向对象的HQL查询语言 QBC检索方式:使用QBC(Query By Criteria)API来检索对象.这种API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口 本地SQL检索方式:使用本地数据库的SQL查询语句 本文主要介绍第三种方式,也就是HQL检索对象. HQL(Hibernate Quer

【HQL】hibernate查询语言hql

hibernate查询语言hql 在hql中关键字不区分大小写,通常小写,类的名称和属性名称必须区分大小写 1.简单属性查询[重要] * 单一属性查询,返会属性结果集列表,元素类型和实体类中相应的类型一致 * 多个属性查询,多个属性查询返会对象数组,对象数组的长度取决于属性的个数 对象数组中元素的类型取决于属性在实体类中的类型 * 如果认为返会数组不够对象化,可以使用hql动态实例化Student对象 参见:SimplePropertyQueryTest.java 2.实体对象查询[重要] *

Hibernate六 HQL查询

HQL查询一 介绍1.HQL:Hibernate Query Language,是一种完全面向对象的查询语言.使用Hibernate有多重查询方式可供选择:hibernate的HQL查询,也可以使用条件查询,甚至使用原生的SQL查询语句.Hibernate还提供了一种数据过滤功能,这些都用于删选目标数据.2.查询步骤:(1)获取Hibernate Session对象(2)编写HQL语句(3)以HQL语句为参数,调用Session的createQuery()方法创建查询对象(4)如果HQL语句包含

Hibernate学习---第九节:Hibernate之hql

一.Hql 入门 1.实体类: package learn.hibernate.bean; import java.util.Date; import java.util.HashSet; import java.util.Set; /** * 持久化类设计 * 注意: * 持久化类通常建议要有一个持久化标识符(ID) * 持久化标识符通常建议使用封装类(例如:Integer 因为基本类型存在默认值) * 持久化类通常建议手动添加一个无参构造函数 (因为有些操作是通过放射机制进行的) * 属性通

Java_Web三大框架之Hibernate+jsp+HQL分页查询

分页查询无处不在.使用Hibernate+jsp+HQL进行分页查询. 第一步:编写房屋实体类和House.hbm.xml映射. /* * 房屋实体类 */ public class House { private int id;//房屋id private HouseType type;//房屋类型 private Users2 user;//用户 private Street street;//街道 private String title;//标题 private String descr

hibernate的hql查询语句

hibernate的hql查询语句 在这里通过定义了三个类,Special.Classroom.Student来做测试,Special与Classroom是一对多,Classroom与Student是一对多的关系,这里仅仅贴出这三个bean的属性代码: Special类: public class Special { private int id; private String name; private String type; private Set<Classroom> rooms; .

Hibernate中HQL函数汇总及其说明

Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Language)查询提供了更加丰富的和灵活的查询特性,因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,HQL查询在涵盖Criteria查询的所有功能的前提下,提供了类似标准SQL语句的查询方式,同时也提供了更加面向对象的封装.以下就是HQL的一些常用函数,有了这些函数,我们就可以拥有更多的灵活性,比如HQL如何取余,HQL如何返回集合的最值,HQL字符串处理,

hibernate 之 HQL语句总结【转】

1. 查询整个映射对象所有字段 //直接from查询出来的是一个映射对象,即:查询整个映射对象所有字段 String hql = "from Users"; Query query = session.createQuery(hql); List<Users> users = query.list(); for(Users user : users){ System.out.println(user.getName() + " : " + user.ge

hibernate注解HQL 报错

@Entity(name="icertInfo") HQL  查询的时候 需要写Entry 的name值,要不然会报错 iCertInfo is not mapped <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 用户名 --> <property name="user" value=&q

Hibernate之HQL基本用法

关于HQL HQL与SQL非常类似,只不过SQL的操作对象是数据表,列等对象,而HQL操作的是持久化类,实例,属性等. HQL是完全面向对象的查询语言,因此也具有面向对象的继承,多态等特性. 使用HQL的一般步骤为: 获取session对象 编写HQL语句 使用session的createQuery方法创建查询对象(Query对象) 使用SetXxx(index/para_name, value)为参数复制 使用Query对象的list()方法返回查询结果列表(持久化实体集) 下面演示一下HQL