简体   繁体   English

用于一对多关系的 Spring Data JPA Select

[英]Spring Data JPA Select for OneToMany relationship

I have two entities我有两个实体

Box(id, srNo, boxNumber, basePrice, baseAmount)

Lot(id, lotNumber, size, description, pcs, weight, box_id)

One box has many lots一盒有很多
Now, i want to find out box with lot details(boxId, srNo, boxNumber, basePrice, lotId, lotNumber, size)现在,我想找出带有批次详细信息的框(boxId、srNo、boxNumber、basePrice、lotId、lotNumber、size)
in a programmatic way(Criteria or queryDSL) with the use of only a single select query以编程方式(Criteria 或 queryDSL),只使用一个选择查询

With Criteria API:使用标准 API:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<YourPojo> cq = cb.createQuery(YourPojo.class);

Root<Box> rootBox = cq.from(Box.class);
Join<Box,Lot> joinLot = rootBox.join(Box_.lots,JoinType.LEFT);

List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(joinLot.get(Lot_.id), ID_LOT))
cq.where(predicates.toArray(new Predicate[predicates.size()]));

cq.multiselect(
    rootBox.get(Box_.id),
    rootBox.get(Box_.srNo),
    rootBox.get(Box_.boxNumber),
    rootBox.get(Box_.basePrice),
    rootBox.get(Box_.baseAmount),
    joinLot.get(Let_.id),
    joinLot.get(Let_.lotNumber),
    joinLot.get(Let_.size),
    joinLot.get(Let_.description),
    joinLot.get(Let_.pcs),
    joinLot.get(Let_.weight)
);

List<YourPojo> result = entityManager.createQuery(cq).getResultList();

and the following constructor in your YourPojo.java:以及 YourPojo.java 中的以下构造函数:

public YourPojo(Long id, String srNo, Integer boxNumber, Long basePrice, Long 
    baseAmount, Long idLot, Integer lotNumber, Long size, String description, 
    Integer pcs, Long weight){
     ....
}

In this way you will get an object for each Box-Lot entry.通过这种方式,您将为每个 Box-Lot 条目获得一个对象。

Another way to do it, for me less optimal is the following: CriteriaBuilder cb = entityManager.getCriteriaBuilder();另一种对我来说不太理想的方法是: CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(Box.class); CriteriaQuery cq = cb.createQuery(Box.class);

Root<Box> rootBox = cq.from(Box.class);
Join<Box,Lot> joinLot = (Join<Box,Lot>)rootBox.fetch(Box_.lots,JoinType.LEFT);

List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(joinLot.get(Lot_.id), ID_LOT))
cq.where(predicates.toArray(new Predicate[predicates.size()]));

cq.select(rootBox);

List<Box> result = entityManager.createQuery(cq).getResultList();

In this way you will obtain a list of Box entities, with the parameter Lots (List or Lot set) fed.通过这种方式,您将获得一个 Box 实体列表,其中包含参数批次(列表或批次集)。

I prefer the first mode since even if you have N inputs to deal with the streams and lambdas of Java 8 it is very simple, and in case of being an API it is a security flaw to expose entities, in this way you would work with flat objects.我更喜欢第一种模式,因为即使你有 N 个输入来处理 Java 8 的流和 lambda,它也非常简单,而且如果是 API,暴露实体是一个安全缺陷,这样你就可以使用平面物体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM