【问题标题】:Can I execute @Query with aggregate function with Specifications on one Spring Data JPA repository method?我可以在一个 Spring Data JPA 存储库方法上使用带有规范的聚合函数执行 @Query 吗?
【发布时间】:2016-01-19 16:26:33
【问题描述】:

我有与previously asked 非常相似的问题。 除了在我的情况下查询即将找到多个 sum()

public interface IQuotaRepository extends JpaRepository<QuotaDao, Long>, JpaSpecificationExecutor<QuotaDao> {

        @Query( "select new ca.quota.kpi.model.dto.TotalDto(sum(q.value1), sum(q.value2), sum(q.value3), sum(q.value4), "
                                                                + "sum(q.value5), sum(q.value6), sum(q.value7), sum(q.value8), "
                                                                + "sum(q.value9), sum(q.value10), sum(q.value11), sum(q.value12)) from QuotaDao q")
        public TotalDto sumQuota();//Specification<QuotaDao> spec

        @Query( "select new ca.quota.kpi.model.dto.TotalDto(sum(q.value1), sum(q.value2), sum(q.value3), sum(q.value4), "
                                                                + "sum(q.value5), sum(q.value6), sum(q.value7), sum(q.value8), "
                                                                + "sum(q.value9), sum(q.value10), sum(q.value11), sum(q.value12)) from QuotaDao q")
        public TotalDto sumQuotaWithSpec(Specification<QuotaDao> spec);
}
  • sumQuota() 工作正常
  • sumQuotaWithSpec(Specification spec) 抛出一个 QueryParameterException:位置超出了声明的序数参数的数量。请记住,序数参数是基于 1 的!职位:1

我希望重用“规范规范”来过滤来自网格控件的各种参数的结果。

您能否建议任何解决方案或替代方案

【问题讨论】:

  • 你得到答案了吗,我也面临同样的问题。
  • @Anchit Pancholi 。我已经发布了答案

标签: hibernate jpa spring-data-jpa


【解决方案1】:

嗯... 我发现解决方案可能比严格的 JPA 方法更适合

首先我在存储库接口中声明了方法

public interface IQuotaRepositoryCustom{

    public TotalDto sumQuotaWithFilters(FilterParameterExtJs6[] filters);
    ...
}

然后在仓库实现中实现这个方法

@Repository
public class IQuotaRepositoryImpl implements IQuotaRepositoryCustom {
    private static Logger logger = Logger.getLogger(IQuotaRepositoryImpl.class);    
    private final String SELECT_COUNT_FOR_TOTAL = "select count(*)";
    private final String SELECT_COUNT_FOR_TOTAL_QUOTA = SELECT_COUNT_FOR_TOTAL + " from QuotaDao q";
    private final String SELECT_TOTAL = "select new org.avp.quota.kpi.model.dto.TotalDto(sum(q.value1), sum(q.value2), sum(q.value3), sum(q.value4), "
                                                                                    + "sum(q.value5), sum(q.value6), sum(q.value7), sum(q.value8), "
                                                                                    + "sum(q.value9), sum(q.value10), sum(q.value11), sum(q.value12))";

private final String SELECT_TOTAL_QUOTA = SELECT_TOTAL + " from QuotaDao q";
    ...
    public TotalDto sumQuotaWithFilters(FilterParameterExtJs6[] filters) {
        String countHql = SELECT_COUNT_FOR_TOTAL_QUOTA + buildWhereClause(filters);
        Query countQuery = em.createQuery(countHql.toString());
        Long count = (Long)countQuery.getSingleResult();
        if(count.longValue() == 0L)
            return new TotalDto();
        String hql = SELECT_TOTAL_QUOTA+ buildWhereClause(filters);
        Query query = em.createQuery(hql.toString());
        return (TotalDto) query.getSingleResult();
    }
}

TotalDto 是普通的数据传输对象

    public class TotalDto {

        private long value1;
        private long value2;
        private long value3;
        private long value4;
        private long value5;
        private long value6;
        private long value7;
        private long value8;
        private long value9;
        private long value10;
        private long value11;
        private long value12;
        private long total;
// constructor and getters/setters removed
}

本地辅助函数,顾名思义,只是构建 where 子句字符串(我不发布代码,因为来自 UI 的格式非常特殊)

private String buildWhereClause(FilterParameterExtJs6[] filterParameters) {
    StringBuffer sb = new StringBuffer();
    // Build where clause string 
    return sb.toString();
}

终于在服务中调用这个存储库方法

public TotalDto getFilteredSummAggregateQuota(final FilterParameterExtJs6[] filterParameters){
    TotalDto aggregateTotalQuota = quotaRepository.sumQuotaWithFilters(filterParameters);
    return aggregateTotalQuota;
}

希望这将帮助您解决问题。

【讨论】:

  • 好的,但这不是 JPA 的正确方法,所以我为此使用了 QueryDSL。
  • @AlexeiP,请参阅 - cfmtips.blogspot.com/2016/08/…。它也解释了关系。
  • @Shamseer 非常有趣。谢谢。
猜你喜欢
  • 2014-12-10
  • 2020-05-20
  • 1970-01-01
  • 2019-05-06
  • 1970-01-01
  • 2019-04-29
  • 2015-03-15
  • 2020-07-07
  • 2021-11-02
相关资源
最近更新 更多