hibernate之HQL

亚洲365 2025-07-11 20:55:47 admin

1. 什么是hql

HQL是Hibernate Query Language的缩写

2. hql和sql区别/异同

HQL SQL

类名/属性 表名/列名

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

别名 别名

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

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

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

sql:select name from t_mvc_book where name like ?,?,?,?,?,?,?,?,?hql:from Book where name like :bookName,:price,:sex::age

query.setParam('bookName':圣墟)

注1:QuerySyntaxException:book is not mapped

3. 处理返回的结果集

3.1 单个对象

select没有逗号

3.2 Object[]

b.bookId, b.bookName

3.3 Map

new Map(b.bookId as bid, b.bookName as bname)

3.4 new 构造方法(attr1,attr2)

new Book(b.bookId, b.price)

单个列段4. hql中使用占位符

4.1 ?占位符

从下标0开始计算位置

hibernate5之后不再支持?占位符

4.2 :命名参数5. 连接查询

6. 聚合函数

sum

avg

max

min

count

7. hql分页

int page = 2;// 页码:page

int row = 10;// 每页行数:rows

query.setFirstResult((page - 1) * row);// 设置起始记录下标

query.setMaxResults(row);// 设置返回的最大结果集

一.hql语法基础

1.实体类

package com.zy.two.entity;

import java.io.Serializable;

import java.util.HashSet;

import java.util.Set;

public class Book implements Serializable{

// book_id int primary key auto_increment,

// book_name varchar(50) not null,

// price float not null

private Integer bookId;

private String bookName;

private Float price;

private Set categories = new HashSet();

private Integer initCategories = 0;

public Integer getInitCategories() {

return initCategories;

}

public void setInitCategories(Integer initCategories) {

this.initCategories = initCategories;

}

public Integer getBookId() {

return bookId;

}

public void setBookId(Integer bookId) {

this.bookId = bookId;

}

public String getBookName() {

return bookName;

}

public void setBookName(String bookName) {

this.bookName = bookName;

}

public Float getPrice() {

return price;

}

public void setPrice(Float price) {

this.price = price;

}

public Set getCategories() {

return categories;

}

public void setCategories(Set categories) {

this.categories = categories;

}

@Override

public String toString() {

return "Book [bookId=" + bookId + ", bookName=" + bookName + ", price=" + price + "]";

}

public Book(Integer bookId, String bookName) {

super();

this.bookId = bookId;

this.bookName = bookName;

}

public Book() {

super();

}

}

2. HqlTest处理返回的结果集

package com.zy.three.hql;

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.zy.two.entity.Book;

import com.zy.two.util.SessionFactoryUtil;

public class HqlTest {

private Session session;

private Transaction transaction;

@Before

public void before() {

session = SessionFactoryUtil.getSession();

transaction = session.beginTransaction();

}

@After

public void after() {

transaction.commit();

session.close();

}

/**

* 返回对象(多个)

*/

@Test

public void testList1() {

Query query = session.createQuery("from Book");

List 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 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 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 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 list = query.list();

for (Book b : list) {

System.out.println(b);

}

}

/**

* HQL语句支持占位符

* query对象相当于preparestament

* 传数组,也可以传集合

*/

@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 params = new ArrayList();

// params.add(1);

// params.add(2);

// params.add(4);

// query.setParameterList("bookIds", params);

List 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 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");

//getSingleResult返回单行单列的数据

Long singleResult = (Long) query.getSingleResult();

System.out.println(singleResult);

}

@Test

public void testList10() {

String hql="from Book where 1 =1";

Book book=new Book();

if(book.getBookId()!=0) {

hql+=" and bookId=:bookId";

}

if(book.getBookName()!=null) {

hql+=" and bookName=:bookName";

}

Query query = session.createQuery("hql");

if(book.getBookId()!=0) {

query.setParameter("bookId", 1);

}

if(book.getBookName()!=null) {

query.setParameter("bookName", "%西%");

}

Book b = (Book) query.getSingleResult();

System.out.println(b);

}

/**

* HQL分页

* FirstResult:起始下标

* setMaxResults:偏移量,代表页大小

*/

@Test

public void testList9() {

Query query = session.createQuery("from Book");

query.setFirstResult(2);

query.setMaxResults(3);

List list = query.list();

for (Book b : list) {

System.out.println(b);

}

}

二.BaseDAO

1.工具类:分页

package com.zy.three.hql;

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 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 getParameterMap() {

return parameterMap;

}

public void setParameterMap(Map 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 + "]";

}

}

2 StringUtils

package com.zy.three.hql;

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

}

}

3BaseDao

package com.zy.three.dao;

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;

import com.zy.three.hql.PageBean;

/**

* 1、设置参数的问题 2、分页代码重复的问题

*

* sql的通用分页的时候

*

* 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" select

* count(1) hql

*

* @author Administrator

*

*/

public class BaseDao {

/**

* 通用的参数设值方法

*

* @param map

* 参数键值对集合

* @param query

* 预定义处理的hql对象

*/

public void setParam(Map map, Query query) {

if (map != null && map.size() > 0) {

Object value = null;

Set> entrySet = map.entrySet();

for (Entry 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"

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 map,String hql,PageBean pageBean) {

List list = null;

if(pageBean != null && pageBean.isPagination()) {

String countHql = getCountHql(hql);

Query countQuery = session.createQuery(countHql);

this.setParam(map, countQuery);

pageBean.setTotal(countQuery.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;

}

}

4.BookDao extends BaseDao

package com.zy.two.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.zy.three.dao.BaseDao;

import com.zy.three.hql.PageBean;

import com.zy.three.hql.StringUtils;

import com.zy.two.entity.Book;

import com.zy.two.entity.Category;

import com.zy.two.util.SessionFactoryUtil;

public class BookDao extends BaseDao{

public Integer addBook(Book book) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

Integer bid = (Integer) session.save(book);

transaction.commit();

session.close();

return bid;

}

public Integer addCategory(Category category) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

Integer cid = (Integer) session.save(category);

transaction.commit();

session.close();

return cid;

}

public Category getCategory(Category category) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

Category c = session.get(Category.class, category.getCategoryId());

transaction.commit();

session.close();

return c;

}

public Book getBook(Book book) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

Book b = session.get(Book.class, book.getBookId());

if (b != null && new Integer(1).equals(book.getInitCategories())) {

Hibernate.initialize(b.getCategories());

}

transaction.commit();

session.close();

return b;

}

public void delBook(Book book) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

session.delete(book);

transaction.commit();

session.close();

}

public void delCategory(Category category) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

Category c = session.get(Category.class, category.getCategoryId());

if(c!=null) {

for (Book b : c.getBooks()) {

// 通过在被控方通过主控方来解除关联关系,最后被控方再做删除

b.getCategories().remove(c);

}

}

session.delete(c);

transaction.commit();

session.close();

}

/*

* hql讲解用到(需要继承BaseDao)

*/

/**

* 没有使用BaseDao之前的代码

* @param book

* @param pageBean

* @return

*/

public List list(Book book, PageBean pageBean) {

Session session = SessionFactoryUtil.getSession();

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 list = query.list();

transaction.commit();

session.close();

return list;

}

/**

* 使用BaseDao之后的代码

* @param book

* @param pageBean

* @return

*/

public List list2(Book book, PageBean pageBean) {

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

String hql = "from Book where 1 = 1";

Map map = new HashMap();

if (StringUtils.isNotBlank(book.getBookName())) {

hql += " and bookName like :bookName";

map.put("bookName", book.getBookName());

}

List list = super.executeQuery(session, map, hql, pageBean);

transaction.commit();

session.close();

return list;

}

/**

* 使用原生SQL

* @param book

* @param pageBean

* @return

*/

public List list3(Book book, PageBean pageBean) {

//String sql = "select b.*,o.* from t_hibernate_book b,t_hibernate_Order o";

String sql = "select * from t_hibernate_book";

Session session = SessionFactoryUtil.getSession();

Transaction transaction = session.beginTransaction();

List list = session.createSQLQuery(sql).list();

transaction.commit();

session.close();

return list;

}

}

5.测试

@Test

public void testList1() {

PageBean pageBean=new PageBean();

pageBean.setRows(3);

Book book=new Book();

//book.setBookName("%圣墟%");

List list = this.bookDao.list(book, pageBean);

for (Book b : list) {

System.out.println(b);

}

// c.getBooks().add(book);

}

@Test

public void testList2() {

PageBean pageBean=new PageBean();

pageBean.setRows(3);

Book book=new Book();

book.setBookName("%圣墟%");

List list = this.bookDao.list2(book, pageBean);

for (Book b : list) {

System.out.println(b);

}

// c.getBooks().add(book);

}

@Test

public void testList3() {

PageBean pageBean=new PageBean();

pageBean.setRows(3);

Book book=new Book();

book.setBookName("%圣墟%");

List list = this.bookDao.list3(book, pageBean);

for (Object[] o : list) {

System.out.println(Arrays.toString(o));

}

// c.getBooks().add(book);

}