【问题标题】:Spring Data JPA Select for OneToMany relationshipSpring Data JPA Select for OneToMany 关系
【发布时间】:2021-02-10 17:32:44
【问题描述】:

我有两个实体

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

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

一箱多批
现在,我想找出带有批次详细信息的盒子(boxId、srNo、boxNumber、basePrice、lotId、lotNumber、大小)
以编程方式(标准或 queryDSL),仅使用单个选择查询

【问题讨论】:

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


    【解决方案1】:

    使用标准 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();
    

    以及 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){
         ....
    }
    

    通过这种方式,您将为每个 Box-Lot 条目获取一个对象。

    另一种对我来说不太理想的方法如下: CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 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();
    

    通过这种方式,您将获得一个 Box 实体列表,其中包含参数批次(列表或批次集)。

    我更喜欢第一种模式,因为即使你有 N 个输入来处理 Java 8 的流和 lambda,它也非常简单,而且如果是 API,暴露实体是一个安全漏洞,这样你可以处理扁平物体。

    【讨论】:

      猜你喜欢
      • 2019-10-25
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 2016-01-09
      • 2017-05-29
      • 1970-01-01
      • 2019-01-12
      相关资源
      最近更新 更多