JPA & Criteria API 特定 select 离子,用 select 提取
JPA & Criteria API specific selection, extract with select
任务是按特定日期对事件进行分组,为此,我必须从日期中提取日期并按它对记录进行分组。
我们曾经使用 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)
是否可以通过条件 API 获得我需要的内容?征求关于自定义 selection 的建议,select 只是我需要的。
改变
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")));
之后代码正常工作
任务是按特定日期对事件进行分组,为此,我必须从日期中提取日期并按它对记录进行分组。 我们曾经使用 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)
是否可以通过条件 API 获得我需要的内容?征求关于自定义 selection 的建议,select 只是我需要的。
改变
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")));
之后代码正常工作