【问题标题】:Spring JPA Specification One to Many Join 3 tablesSpring JPA 规范一对多连接 3 个表
【发布时间】:2021-09-07 16:49:29
【问题描述】:

我有 3 个具有以下关系的实体。

@Table(name = "a")
@Entity
public class A{
   @Id 
   @GeneratedValue
   @Column(name = "a_uuid")
   @OneToMany(mappedBy = "a", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   private List<B> bList;

   @OneToMany(mappedBy = "a", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   private List<C> cList;

}

@Table(name = "b")
@Entity
public class B{
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(fetch = "a_uuid")
   private A a;
}

@Table(name = "c")
@Entity
class C{
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(fetch = "a_uuid")
   private A a;
}

我需要加入以上三个表,并且我为每个表使用单独的规范

@Component
public class SpecificationTableAUtil {
    public Specification<A> tableACriteriaMatches(final SomeCriteria criteria) {
return (root, query, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList .add(
                    criteriaBuilder.isNull(
                            root.get("some_column_in_table_a")));
            Predicate[] predicates = new Predicate[predicateList.size()];
            return criteriaBuilder.and(predicateList.toArray(predicates ));
        };
     }
   }
}

@Component
public class SpecificationTableBUtil {
    public Specification<A> tableBCriteriaMatches(final SomeCriteria criteria) {
return (root, query, criteriaBuilder) -> {
            ListJoin<A, B> b =
                root.joinList("bList", JoinType.LEFT);
            List<Predicate> predicateList = new ArrayList<>();
            predicateList .add(
                    criteriaBuilder.isNull(
                            b.get("some_column_in_table_b")));
            Predicate[] predicates = new Predicate[predicateList.size()];
            return criteriaBuilder.and(predicateList.toArray(predicates ));
        };
     }
   }
}

来自我的服务类,

@Service
public class ServiceClass{
    //Autowire the utilities
    public Specification<A> getSpecification(final SomeCriteria criteria) {
            return bUtil.tableBCriteriaMatches(criteria)
                   .and(aUtil.tableACriteriaMatches(criteria));
     }
   }
}

现在我也需要加入表 C。如何以更好的方式实现这一点?我需要让每个方法的代码行尽可能小

【问题讨论】:

    标签: hibernate jpa spring-data-jpa jpa-2.0 hibernate-criteria


    【解决方案1】:

    我自己想出来的。这就是我想出的。

    @Component
    public class SpecificationTableAUtil {
    
        @Autowired 
        private SpecificationTableBUtil bSpecificationUtil;
    
        public Specification<A> tableACriteriaMatches(final SomeCriteria criteria) {
    return (root, query, criteriaBuilder) -> {
                List<Predicate> predicateList = new ArrayList<>();
                predicateList .add(
                        criteriaBuilder.isNull(
                                root.get("some_column_in_table_a")));
                predicateList.add(bSpecificationUtil.criteriaMatches(criteria).toPredicate(root, query, criteriaBuilder));
                Predicate[] predicates = new Predicate[predicateList.size()];
                return criteriaBuilder.and(predicateList.toArray(predicates ));
            };
         }
       }
    }
    

    对于表 B 规范,

    @Component
    public class SpecificationTableBUtil {
        public Specification<A> tableBCriteriaMatches(final SomeCriteria criteria) {
    return (root, query, criteriaBuilder) -> {
                ListJoin<A, B> b =
                    root.joinList("bList", JoinType.LEFT);
                List<Predicate> predicateList = new ArrayList<>();
                predicateList .add(
                        criteriaBuilder.isNull(
                                b.get("some_column_in_table_b")));
                Predicate[] predicates = new Predicate[predicateList.size()];
                return criteriaBuilder.and(predicateList.toArray(predicates));
            };
         }
       }
    }
    

    来自服务类,

    @Service
    public class ServiceClass {
       
        @Autowired
        private SpecificationTableAUtil aSpecificationUtil;
       
        public Specification<A> getSpecification(final SomeCriteria criteria) {
                return aSpecificationUtil.tableACriteriaMatches(criteria);
         }
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-06-22
      • 2017-08-19
      • 2017-10-28
      • 2018-05-07
      • 2017-05-12
      • 1970-01-01
      • 2020-05-25
      • 1970-01-01
      • 2016-07-09
      相关资源
      最近更新 更多