【问题标题】:How to define multiple Join on condition using ctiteria API spring data JPA Specification?如何使用ctiteria API spring data JPA规范定义多个条件连接?
【发布时间】:2020-05-16 22:26:23
【问题描述】:

下面是fetch join的代码

public static Specification<Item> findByCustomer(User user) {
    return (root, criteriaQuery, criteriaBuilder) -> {
       root.fetch(User_.address, JoinType.LEFT);
        return criteriaBuilder.equal(root.get(User_.id), 1);
    };
}

上面的代码正在生成下面的查询

select us.ALL_COLUMN, adr.ALL_COLUMN from User us left outer join Address adr on us.id= adr.id where us.id = 1;

如何在左外连接上添加多个条件。我想使用 spring data jpa Specification 生成以下查询。

Select us.ALL_COLUMN, adr.ALL_COLUMN from User us left outer join Address adr on us.id= adr.id 和 adr.effect_end_date = null 其中 us.id = 1

【问题讨论】:

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


    【解决方案1】:

    按照我们可以做的方式,我们应该有两个预测,然后对于这两个预测,没有测试

    public static Specification<Item> findByCustomer(User user) {
            return (root, criteriaQuery, criteriaBuilder) -> {
               root.fetch(User_.address, JoinType.LEFT);
        Predicate predicateForEndDate
          = criteriaBuilder.equal(root.get(User_.end_date), null);
        Predicate predicateForUser
          = criteriaBuilder.equal(root.get(User_.id), 1);
    
                return criteriaBuilder.and(predicateForEndDate, predicateForUser)
            };
        }
    

    【讨论】:

    • 以上代码将在 us.ID=ad.Id 上生成左外层,其中 us.Id= 1 和 ad.endDate 为空,我希望在 userId=addressId 和 address.endDate 上左外层为空用户 ID = 1;
    【解决方案2】:
    public static Specification<A> findAbyBname(String input) {
            return new Specification<A>() {
                @Override
                public Predicate toPredicate(Root<A> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                    cq.distinct(true);
                    Join<A,AB> AjoinAB = root.joinList(A_.AB_LIST,JoinType.LEFT);
                    Join<AB,B> ABjoinB = AjoinAB.join(AB_.B,JoinType.LEFT);
                    return cb.equal(ABjoinB.get(B_.NAME),input);
                }
            };
        }
    

    我有这样的东西。以下是实体:

    @Entity
    public class A {
        @Id
        private Long id;
        private String name;
        @OneToMany(mappedBy = "a")
        private List<AB> abList;
    }
    @Entity
    public class B {
        @Id
        private Long id;
        private String name;
        @OneToMany(mappedBy = "b")
        private List<AB> abList;
    }
    @Entity
    public class AB {
        @Id
        private Long id;
        private String name;
        @ManyToOne
        @JoinColumn(name = "a_id")
        private A a;
        @ManyToOne
        @JoinColumn(name = "b_id")
        private B b;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-12
      • 2018-11-17
      • 2021-04-20
      • 2017-10-28
      • 2016-01-06
      • 2019-05-25
      • 2021-09-07
      • 2017-01-29
      相关资源
      最近更新 更多