如何使用JPA和JpaSpecificationExecutor按结果分组?

时间:2014-09-01 12:41:54

标签: hibernate jpa-2.0 spring-data spring-data-jpa

我正在使用JpaSpecificationExecutor,JPA 2.0,Hibernate和MSSQL,并希望使用CriteriaBuilder构建以下查询:

SELECT CURR_DATE, MAX(POSITION) FROM TOP_COMPONENT_HISTORY GROUP BY CURR_DATE

我的问题:可能吗?如果,怎么样?

感谢您关注此事!

这是我的代码..

表(TOP_COMPONENT_HISTORY)

1   ARC_ID  varchar NO          
2   CURR_DATE   varchar NO          
3   REG_DATE    datetime2   YES         7
4   APPLY_DATE  datetime2   YES         7
5   POSITION    int YES 10  0   
6   REG_USER_ID varchar NO          
7   MOD_USER_ID varchar NO  

服务

public Page<TopComponentHistory> findByCurrDate(ArticleSearchForm searchForm){
        return topComponentHistoryRepository.findAll(TopComponentHistory.findAllGroupBy(),constructPageSpecification(searchForm.getPageNum());
    }

public class TopComponentHistory implements Serializable {
    public static Specification<TopComponentHistory> findAllGroupBy() {     
       How can i make query...
       return ..
    }
}

存储库

public interface TopComponentHistoryRepository extends JpaRepository<TopComponentHistory, String>, JpaSpecificationExecutor<TopComponentHistory> {


}

2 个答案:

答案 0 :(得分:2)

public static Specification<TopComponentHistory> findAllGroupBy() {
        return new Specification<CompPlanID>(){
            @Override
            public Predicate toPredicate(Root<TopComponentHistory> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
    query.groupBy(column_name);
    }
    }

答案 1 :(得分:1)

我使用带有一些自定义规范的泛型类,虽然有点脏,但是可以工作。 它与根实体中的列名称一起使用,如果需要按其他列分组,则有必要修改代码,但是该代码可以作为起点。

public class GenericSpecifications<T> {


public Specification<T> groupBy(Specification<T> specification, List<String> columnNames) {
    return new Specification<T>() {

        @Override
        public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {

            List<Expression<?>> columnNamesExpression = columnNames.stream().map(x -> root.get(x))
                    .collect(Collectors.toList());

            query.groupBy(columnNamesExpression);
            return specification.toPredicate(root, query, criteriaBuilder);
        }
    };
}

然后例如在您需要按功能分组的类中:

GenericSpecifications<YourEntity> genericSpecifications = new GenericSpecifications<YourEntity>();
    ..
    Specification<YourEntity> specification = Specification.where(null);
    ..
    specification = genericSpecifications.groupBy(specification, names);
    YourEntityRepository.findAll(specification);