也许问题有点不寻常,我只是不知道Criteria如何运作(非常肯定,因为我刚开始学习它)但现在我对以下问题感到困惑:
我实现了一个过滤功能,可以按特定条件填充一组记录。所以我们假设有以下实体:
@Entity
public class Car {
@OneToMany
private List<Deal> deals;
}
@Entity
public class Deal {
private Customer customer;
private DateTime dealDate;
}
现在我必须通过第一个客户名称来过滤汽车记录。所以在理论上它看起来像:
private static List<Predicate> buildPredicates(Root root, CriteriaQuery query,
CriteriaBuilder builder, CarFilter filter) {
List<Predicate> predicates = new ArrayList<>();
...
predicates.add(
builder.like(
root.get(Car_.deals.sortByDealDateComparator().first().customer.name),
filter.getFirstCustomerName()));
...
return predicates;
}
我相信这些交易应该首先加入,然后以某种子查询或其他方式进行排序。但是,如何使用CriteriaQuery获得第一个比较结果也很有趣。
我想我的方法不对,所以任何建议都会受到欢迎。
答案 0 :(得分:0)
好吧,你的一些问题是因为你的实体hierarchy
。您在层次结构的根目录中有Cars
,但您需要使用Deals
。如果您使用Deals
,可以(或多或少)直接获得您想要的内容:
CriteriaQuery<Deal> q = cb.createQuery(Deal.class);
Root<Deal> root = q.from(Deal.class);
CriteriaQuery<Deal> s = q.select(root).where(
cb.like(root.get("customer").get("name").as(String.class), "Karl" )
).orderBy(cb.asc(root.get("dealDate")));
Deal deal = em.createQuery(s).getResultList().get(0);
当然,我没有尝试使用实体的元数据版本。这里,根设置为Deal
。 like
predicate
用于按名称获取Customers
,并使用cb.asc
对结果列表进行排序。第一个Deal
取自结果列表,其中包含Customer
。
如果您想返回Car
,则需要bidirectional
关系映射,您可以将Car
添加到Deal
并映射到{{1} }}
ManyToOne
可能或可能没有帮助,但这应该给你一些思考。