Hibernate的HQL
简单介绍HQL
HQL是Hibernate Query Language的缩写,提供更加丰富灵活、更为强大的查询能力;HQL更接近SQL语句查询语法。
Hibernate 查询语言(HQL)是一种面向对象的查询语言,类似于 SQL,但不是去对表和列进行操作,而是面向对象和它们的属性。 HQL 查询被 Hibernate 翻译为传统的 SQL 查询从而对数据库进行操作。
Hibernate查询语言(HQL)与SQL(结构化查询语言)相同,但不依赖于数据库表。 我们在HQL中使用类名,而不是表名,它是数据库独立的查询语言。
HQL的优点
数据库独立
支持多态查询
易于Java程序员学习
hql和sql区别/异同
1,sql里用的是表名与列段名,而hql里用的是类名以及它的属性名
2,在sql语句里是不区分大小写的,hql语句里区分大小写,关键字不区分大小写
3,同样取别名 as *
4,sql的 占位符 ?,从顺序1开始计算位置,hql的占位符 ?,从下标0开始计算位置(hibernate5之后不支持)
5,sql不支持:命名参数,hql支持:命名参数
6,sql 是面向结构的查询语言,hql是面向对象的查询语言
执行HQL查询的步骤:
1、获得HibernateSession对象
2、编写HQL语句
3、调用Session的createQuery方法创建查询对象
4、如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值
5、调用Query对象的list等方法返回查询结果。
编写HQL语句后,使用Session的createQuery(hql)方法创建一个Query,Query对象使用setXxx方法为HQL语句的参数赋值,最后调用list()方法返回查询的全部结果。
在这里Query对象可以连续多次调用setXxx方法为HQL参数赋值。这是因为HibernateQuery的setXxx方法的返回值为Query本身,因此程序创建Query后,可以直接多次调用setXxx方法为HQL语句的参数赋值。
Query对象还包含如下两个方法:
setFirstResult(intfirstResult):设置返回的结果集从第几条记录开始。
setMaxResult(intmaxResult):设置本次查询返回的结果数目。
这两个方法用于对HQL查询实现分页控制
下面会显示我的代码,可以用来帮助理解
处理返回的结果集
1,返回对象(多个)
2,返回单个列段,用字符串就可以接受
3,查两个列段及以上,默认返回的是Object【】
4,注意map是函数,所以不区分大小写,返回的是map集合
5,查两个列段及以上,也可返回对象,前提是有对应的构造函数
HQL支持占位符,支持连接查询,支持聚合函数,HQL操作分页
JUnit测试类:
package com.hsl.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.hsl.four.entity.Book;
import com.hsl.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)");
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);
}
}
}
BookDao类中的方法
(没简化之前,即没使用BaseDao类):
/**
* 没有使用BaseDao之前的代码
* 书籍的分页查询
* 动态的拼接hql语句
* 需要给拼接的hql的语句的命名参数赋值
* @param book
* @param pageBean
* @return
*/
public List<Book> list(Book book, PageBean pageBean) {
Session session = SessionFactoryUtils.openSession();
// Transaction transaction = session.beginTransaction();
String hql = "from Book where 1 = 1";
if (StringUtils.isNotBlank(book.getBookName())) {
hql += " and bookName like :bookName";
}
Query query = session.createQuery(hql);
if (StringUtils.isNotBlank(book.getBookName())) {
query.setParameter("bookName", book.getBookName());
}
if (pageBean != null && pageBean.isPagination()) {
query.setFirstResult(pageBean.getStartIndex());
query.setMaxResults(pageBean.getRows());
}
List<Book> list = query.list();
// transaction.commit();
session.close();
return list;
}
JUnit测试类添加方法:
@Test
public void testList10() {
Book book=new Book();
PageBean pageBean=new PageBean();
// pageBean.setPage(3);
book.setBookName("%魔道%");
List<Book> list=this.bookDao.list(book, pageBean);
for (Book b : list) {
System.out.println(b);
}
}
BookDao类继承BaseDao类后,添加方法:
/**
* 使用BaseDao之后的代码
* @param book
* @param pageBean
* @return
*/
public List<Book> listPlus(Book book, PageBean pageBean) {
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
String hql = "from Book where 1 = 1";
Map<String, Object> map = new HashMap<String, Object>();
if (StringUtils.isNotBlank(book.getBookName())) {
hql += " and bookName like :bookName";
map.put("bookName", book.getBookName());
}
List list = super.executeQuery(hql, pageBean, map, session);
transaction.commit();
session.close();
return list;
}
JUnit测试类添加方法:
@Test
public void testList11() {
Book book=new Book();
PageBean pageBean=new PageBean();
// pageBean.setPage(3);
book.setBookName("%魔道%");
List<Book> list=this.bookDao.listPlus(book, pageBean);
for (Book b : list) {
System.out.println(b);
}
}
帮助类BaseDao类
package com.hsl.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语句的工具类
*
* 基于sql分页查询
* 先查出符合条件的总记录条数
* 再返回符合条件的记录
*
* hql1:from Book where bookName like "%魔道%"
* hql2:select * form Book where bookName like "%魔道%"
* hql3:select count(*) hql
*
* @author Administrator
*
*/
public class BaseDao {
/**
*
* @param query 里面含有带命名参数的hql语句,需等待赋值
* @param paramMap
*/
public void setParam(Query query,Map<String, Object> paramMap) {
if(paramMap!=null&¶mMap.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[]) {
query.setParameter(key, (Object[])value);
}else if(value instanceof Collection) {
query.setParameter(key, (Collection)value);
}else {
query.setParameter(key,value);
}
}
}
}
public String getCountHql(String hql) {
int fromIndex=hql.toUpperCase().indexOf("FROM");
return "select count(*) "+hql.substring(fromIndex);
}
public List executeQuery(String hql,PageBean pageBean,Map<String, Object> map,Session session) {
List list=null;
Query query=null;
if(pageBean!=null&& pageBean.isPagination()) {
String count=getCountHql(hql);
Query conutQuery=session.createQuery(count);
this.setParam(conutQuery, map);
pageBean.setTotal(conutQuery.getQueryString().toString());
query=session.createQuery(hql);
query.setFirstResult(pageBean.getStartIndex());
query.setMaxResults(pageBean.getMaxPage());
this.setParam(query, map);
list=query.list();
}else {
query=session.createQuery(hql);
this.setParam(query, map);
list=query.list();
}
return list;
}
}