当 hql 有 group by 时,如何获取 hibernate 中的行数?

ali*_*ani 5 sql hibernate jpa hql jql

我有具有分组依据的 hql 查询。在分页结果中,我想获取要在分页中显示的所有结果的计数。在没有 group by 的查询中。我编写了一个实用程序,可以像这样从 hql 查询创建查询计数

select u 
from Personel u 
where u.lastname='azizkhani'
Run Code Online (Sandbox Code Playgroud)

我找到主要的“from”关键字和子字符串 hql 并添加 count(*) 然后进行此查询

select count(*) 
from Personel u  
where u.lastname='azizkhani'
Run Code Online (Sandbox Code Playgroud)

当我有包含 group by 的查询时,我不能这样做

select u.lastname,count(*) 
from Personel u 
group by u.lastname;
Run Code Online (Sandbox Code Playgroud)

sql 中该查询的计数是

select count(*) 
   from (
         select u.lastname,count(*) 
         from tbl_personel u 
         group  by u.lastname
    )
Run Code Online (Sandbox Code Playgroud)

我如何通过 hql 查询生成组?

我有 GenericRepository 有这样的方法

public <U> PagingResult<U> getAllGrid(String hql,Map<String, Object> params,PagingRequest searchOption);
Run Code Online (Sandbox Code Playgroud)

开发人员这样称呼它

   String hqlQuery = " select e from Personel e where 1<>2 and e.lastname=:lastname";

    HashMap<String, Object> params = new HashMap<String, Object>();
    params.put("lastname", 'azizkhani');


    return getAllGrid(hqlQuery, params, new PagingRequest( 0/*page*/, 10 /*size*/) );
Run Code Online (Sandbox Code Playgroud)

在 GenericRepository 中我将返回具有属性的 PagingResult 对象

public class PagingResult<T> {

    private int totalElements;

    @JsonProperty("rows")
    private List<T> items;

    public PagingResult() {

    }

    public PagingResult(int totalElements, List<T> items) {
        super();
        this.totalElements = totalElements;
        this.items = items;
    }


    public int getTotalElements() {
        return totalElements;
    }

    public void setTotalElements(int totalElements) {
        this.totalElements = totalElements;
    }


    public List<T> getItems() {
        return items;
    }

    public void setItems(List<T> items) {
        this.items = items;
    }

}
Run Code Online (Sandbox Code Playgroud)

在 GenericRepository 中,我将执行两个查询,第一个查询用于获取 10 个结果,第二个查询用于获取totalRecords。开发人员只需发送 Hql。我将制作 hql 来获取totalcount。对于没有“distinct”或“group by”的查询,我制作 hql 。但是当 hql 有“distinct”和“group by”时,我有问题。

public <U> PagingResult<U> getAllGrid(String hql, Map<String, Object> params, PagingRequest searchOption) {
        Session session = getSession();
        applyDafaultAuthorizeFilter(session);


        Query query = session.createQuery(hql);
        if (searchOption != null) {
            if (searchOption.getSize() > 0) {
                query.setFirstResult(searchOption.getPage() * searchOption.getSize());
                query.setMaxResults(searchOption.getSize());
            }
        }
        if (params != null)
            HQLUtility.setQueryParameters(query, params);

        List<U> list = query.getResultList();

        Query countQuery = session.createQuery("select count(*) " + HQLUtility.retriveCountQueryFromHql(hql));

        if (params != null)
            HQLUtility.setQueryParameters(countQuery, params);

        int count = ((Long) countQuery.uniqueResult()).intValue();
        if (searchOption != null)
            return new PagingResult<U>(searchOption.getPage(), count, searchOption.getSize(), list);
        else
            return new PagingResult<U>(0, count, 0, list);
    }


   public static StringBuffer retriveCountQueryFromHql(StringBuffer jql) {
        if(jql.indexOf("order by")>=0)
            jql.replace(jql.indexOf("order by"), jql.length(),"");
        String mainQuery = jql.toString();

        jql = new StringBuffer(jql.toString().replace('\t', ' '));
        int firstIndexPBas = jql.indexOf(")");
        int firstIndexPBaz = jql.lastIndexOf("(", firstIndexPBas);
        while (firstIndexPBas > 0) {
            for (int i = firstIndexPBaz; i < firstIndexPBas + 1; i++)
                jql.replace(i, i + 1, "*");
            firstIndexPBas = jql.indexOf(")");
            firstIndexPBaz = jql.lastIndexOf("(", firstIndexPBas);
        }
        int Indexfrom = jql.indexOf(" from ");
        return new StringBuffer(" " + mainQuery.substring(Indexfrom, jql.length()));
    }

    public void applyDafaultAuthorizeFilter(Session session) {
        Filter filter = session.enableFilter("defaultFilter");
        filter.setParameter("userId", SecurityUtility.getAuthenticatedUserId());
        filter.setParameter("orgId", SecurityUtility.getAuthenticatedUserOrganization().getId());
    }
Run Code Online (Sandbox Code Playgroud)

我如何在不更改 GenericRepository 签名的情况下解决这个问题???

我认为我有将 hql 转换为 sql 并创建本机查询的解决方案,如下所示 select count(*) from ( hql_to_sql) 但我有两个问题

  1. hql转sql没有支持参数的api
  2. hql 到 sql 没有支持 hibernate 过滤器的 api

小智 -1

将查询的输出分配给列表。

Query query = getEntityManager().createQuery("select u.lastname,count(*) from Personel u group by u.lastname;");

List<YourEntity> list = query.getResultList();
Run Code Online (Sandbox Code Playgroud)

你的计数在这里..

Integer.toString(list.size())