【问题标题】:JPA & Criteria API specific selection, extract with selectJPA & Criteria API 特定选择,使用 select 提取
【发布时间】:2019-10-17 12:43:17
【问题描述】:

任务是按特定日期对事件进行分组,为此,我必须将日期从日期中拉出并按其对记录进行分组。 我们曾经使用 MySql,这段代码可以正常工作:

public static Specification<AllFile> findByGroup(FileFilter fileFilter) {
    return (Specification<AllFile>) (root, query, cb) -> {
        final Collection<Predicate> predicates = new ArrayList<>();

        if (fileFilter.getStart() != null && fileFilter.getEnd() != null) {
            Date date = new Date(fileFilter.getStart().getTime());
            date.setHours(0);
            date.setMinutes(0);
            date.setSeconds(0);
            date.setDate(1);

            predicates.add(cb.greaterThanOrEqualTo(root.get("created"), date));
            predicates.add(cb.lessThanOrEqualTo(root.get("created"), fileFilter.getEnd()));
        }
        else if(fileFilter.getStart() != null) {
            Date date = new Date(fileFilter.getStart().getTime());
            date.setHours(0);
            date.setMinutes(0);
            date.setSeconds(0);
            date.setDate(1);

            Date newDate = DateUtils.addMonths(date, 1);

            predicates.add(cb.greaterThanOrEqualTo(root.get("created"), date));
            predicates.add(cb.lessThanOrEqualTo(root.get("created"), newDate));
        }

        if (fileFilter.getRoute() != null) {
            predicates.add(cb.equal(root.get("route"), fileFilter.getRoute()));
        }

        if (fileFilter.getDevice() != null) {
            predicates.add(cb.equal(root.get("device"), fileFilter.getDevice()));
        }

        if (fileFilter.getType() != null) {
            predicates.add(cb.equal(root.get("type"), fileFilter.getType()));
        }

        if (fileFilter.getUser() != null) {
            predicates.add(cb.equal(root.get("user"), fileFilter.getUser()));
        }

        if (fileFilter.getDeleted() != null) {
            predicates.add(cb.equal(root.get("deleted"), fileFilter.getDeleted()));
        }



        query.groupBy(cb.function("day", Date.class, root.get("created")));
        return cb.and(predicates.toArray(new Predicate[predicates.size()]));
    };
}

但是切换到 Postgres 之后,这种方法就不行了。 我需要发送类似的东西

select extract(day from allfile0_.created) as dd
from all_file allfile0_ 
where allfile0_.created>='Tue Oct 01 00:00:00 MSK 2019' and allfile0_.created<='Fri Nov 01 00:00:00 MSK 2019' 
group by dd

而不是这个

select allfile0_.id as id1_0_, allfile0_.added as added2_0_, allfile0_.comment as comment3_0_, 
allfile0_.created as created4_0_, allfile0_.deleted as deleted5_0_, allfile0_.device_id as 
device_13_0_, allfile0_.duration as duration6_0_, allfile0_.mark as mark7_0_, allfile0_.path as 
path8_0_, allfile0_.recognition as recognit9_0_, allfile0_.route_id as route_i14_0_, allfile0_.size 
as size10_0_, allfile0_.type as type11_0_, allfile0_.updated as updated12_0_, allfile0_.user_id as 
user_id15_0_ 

from all_file allfile0_ 

where allfile0_.created>='2019-10-01 00:00:00' and allfile0_.created<='2019-10-04 00:00:00' 

group by extract(day from allfile0_.created)

是否可以通过 Criteria API 获得我需要的内容?征求关于自定义选择的建议,只选择我需要的。

【问题讨论】:

    标签: java spring-data-jpa criteria-api


    【解决方案1】:

    改变

    query.groupBy(cb.function("day", Date.class, root.get("created")));
    

    query = cb.createTupleQuery();
        root = query.from(AllFile.class);
        query.select(root.get("created")).
                groupBy(cb.function("day", Integer.class, root.get("created")));
    

    之后代码正常工作

    【讨论】:

      猜你喜欢
      • 2012-09-19
      • 2011-03-29
      • 2014-09-02
      • 2015-02-15
      • 2019-11-10
      • 2012-03-08
      • 2016-10-31
      • 2014-06-13
      • 1970-01-01
      相关资源
      最近更新 更多