• 技术经验分享:Hibernate之HQL
  • 2025-05-19 12:01:27
  • 什么是HQL?

    HQL是Hibernate Query Language的缩写,提供更加丰富灵活、更为强大的查询能力;HQL更接近SQL语句查询语法。

    HQL与SQL有何不同:

    1.HQL

    对查询条件进行了面向对象封装,符合编程人员的思维方式,格式:from + 类名 + 类对象 + where + 对象的属性

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

    从下标0开始计算位置(hibernate5之后不支持)

    支持命名参数

    2.SQL

    sql是面向数据库表查询,格式:from + 表名 + where + 表中字段

    不区分大小写

    从顺序1开始计算位置

    不支持:命名参数

    处理返回的结果集

    单个对象

    多个列段

    object【】

    对象(多个列段、全部)

    Map

    这里写了一个JUnit测试类来测试这些效果

    注意:测试类中需要设置session,transaction属性,然后就可以在类中写方法论

    1. 单个对象

    select没有逗号

    如果是单个列段的话,就直接可以用String接收对象,这样就避免一些麻烦

    /

    返回单个列段,用字符串就可以接受

    /

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

    }

    }

    效果:

    2.1 Object【】

    b.bookId, b.bookName...

    如果有两个或者两个以上的列段可以用数组来接收

    /

    查两个列段及以上,默认返回的是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));

    }

    }

    效果:

    2.2 book对象

    其实两个以上也可以用对象来接收

    /

    查两个列段及以上,也可返回对象,前提是有对应的构造函数

    /

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

    }

    }

    效果:

    2.2.1 也是用对象来接收

    /

    返回对象(多个)

    /

    @Test

    public void testList1() {

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

    List list = query.list();

    for (Book b : list) {

    System.out.println(b);

    }

    }

    效果:

    3.Map

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

    /

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

    }

    }

    效果:

    HQL中使用占位符

    占位符从下标0开始计算位置

    hibernate5之后不再支持占位符

    命名参数的使用

    /

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

    }

    }

    //代码效果参考:http://www.jhylw.com.cn/550425681.html

    命名参数的用法就是:

    Query query = session.createQuery("from Book where bookId in (:bookIds)");

    query.setParameterList("bookIds", new Integer【】 {1,2,4});

    连接查询

    /

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

    }

    }

    聚合函数

    sum 总计

    avg 平均值

    max 最大

    min 最小

    count 总数

    /

    HQL支持聚合函数

    /

    @Test

    public void testList8() {

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

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

    System.out.println(singleResult);

    }

    HQL分页

    /**

    HQL分页

    /

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

    }

    }

    使用HQL实现通用查询

    BaseDao类

    这就是通用的实体查询类

    package com.ht.five.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.Query;

    import org.hibernate.Session;

    import com.ht.five.Util.PageBean;

    /**

    通用查询类

    @author Administrator

    /

    public class BaseDao {

    /**

    @param map 将要设置的阐述用Map的形式来传递

    @param query 查询对象

    /

    public void setParam(Map map, Query query) {

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

    Object value = null;

    Set

    for (Entry entry : entries) {

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

    }

    }

    }

    }

    /

    传入hql语句 ,返回该语句所查到的总行数

    @param hql

    @return

    /

    public String getCountHql(String hql) {

    /

    下面这种做法的原因是请看这两条hql语句:

    from Book

    select from Book

    所有要想使这个方法同意就是将from这个位置做截断拼接

    /

    //获取到FROM的位置

    int index = hql.toUpperCase().indexOf("FROM");

    //直接从FROM截断,将select count() 拼接上就ok了

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

    //给预定于的hql语句的命名参数赋值

    this.setParam(map, countQuery);

    //将总行数放入PageBean对象

    pageBean.setTotal(countQuery.getSingleResult().toString());

    Query query = session.createQuery(hql);

    //给预定于的hql语句的命名参数赋值

    this.setParam(map, query);

    //设置开始位置(下标从0开始)

    query.setFirstResult(pageBean.getStartIndex());

    //这是偏移量,就是一页展示几条数据

    query.setMaxResults(pageBean.getRows());

    list = query.list();

    }

    else {

    //如果不分页 直接查

    Query query = session.createQuery(hql);

    this.setParam(map, query);

    list = query.list();

    }

    return list;

    }

    }

    BookDao类