2016-09-21 87 views
2

我使用JPA規範和CriteriaQuery中以where子句添加到我的實體..春天JPA使用上聯合表規格和CriteriaQuery中

域類:

public class Domain { 

    @Id 
    @Column(name = "id") 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Column(name = "account_id") 
    private Long accountId; 

    @OneToMany(cascade = CascadeType.ALL) 
    @JoinColumn(name = "domain_id") 
    private List<Notification> notification; 
} 

通知類:

public class Notification { 

    @Id 
    @Column(name = "id") 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Column(name = "domain_id") 
    private Long domainId; 

    @Column(name = "contact") 
    private String contact; 
} 

然後,我有以下類,我用它來創建產品規格:

public class DomainSpecification implements Specification<Domain> { 

    final private SearchCriteria criteria; 

    public DomainSpecification(SearchCriteria searchCriteria) { 
    this.criteria = searchCriteria; 
    } 

    @Override 
    public Predicate toPredicate(
      Root<Domain> root, CriteriaQuery<?> query, CriteriaBuilder builder) { 

    switch (criteria.getOperation()) { 
     case ":": 
     if (root.get(criteria.getKey()).getJavaType() == String.class) { 
      return builder.like(
        root.<String>get(criteria.getKey()), 
        "%" + criteria.getValue() + "%"); 
     } else { 
      return builder.equal(root.get(criteria.getKey()), 
        criteria.getValue()); 
     } 
     case "=": 
     return builder.equal(root.get(criteria.getKey()), 
       criteria.getValue()); 
     default: 
     return null; 
    } 
    } 

} 

而且SearchCriteria對象:

public class SearchCriteria { 

    private final String key; 
    private final String operation; 
    private final Object value; 

    public SearchCriteria(String key, String operation, Object value) { 
    this.key = key; 
    this.operation = operation; 
    this.value = value; 
    } 

    public String getKey() { 
    return key; 
    } 

    public String getOperation() { 
    return operation; 
    } 

    public Object getValue() { 
    return value; 
    } 

} 

然後,每當我想創建一個WHERE子句,我做到以下幾點:

DomainSpecification idSpecification 
     = new DomainSpecification(
       new SearchCriteria("id", "=", domainId)); 

Specifications<Domain> specifications = Specifications.where(idSpecification); 

final Domain domain = this.domainRepository.findOne(specifications); 

這將通過現場搜索中域稱爲id實體..

現在,我怎樣才能過濾我加入的實體?例如,我想過濾Domain.id = 10和Notification.contact =「abc」?

感謝您的幫助

回答

3

你可以換你Specification界說爲輔助類:

public class DelegationSpecificationsHelper { 

    public static Specification<Domain> notificationContactSpec(String contact) { 
     return (root, query, cb) -> cb.equal(root.join("notification").get("contact"), contact); 
    } 

    public static Specification<Domain> idSpec(SearchCriteria searchCriteria) { 
     switch (criteria.getOperation()) { 
      case ":": 
      if (root.get(criteria.getKey()).getJavaType() == String.class) { 
       return builder.like(
         root.<String>get(criteria.getKey()), 
         "%" + criteria.getValue() + "%"); 
      } else { 
       return builder.equal(root.get(criteria.getKey()), 
         criteria.getValue()); 
      } 
      case "=": 
      return builder.equal(root.get(criteria.getKey()), 
        criteria.getValue()); 
      default: 
      return null; 
     } 
    } 
} 

然後你可以使用這樣的:

Specifications<Domain> specifications = Specifications.where(DelegationSpecificationsHelper.idSpec(new SearchCriteria("id", "=", domainId)) 
                 .and(DelegationSpecificationsHelper.notificationContactSpec("someSearchString")); 

靜態導入後一些重構:

SearchCriteria idCriteria = new SearchCriteria("id", "=", domainId) 
Specifications<Domain> specifications = 
       Specifications.where(idSpec(idCriteria) 
           .and(notificationContactSpec("someSearchString")); 

當然,您應該從這裏刪除硬編碼的值: cb.equal(root.join("notification").get("contact"), contact);並使用一些DTO對象或生成的JPA元模型。

加元模型之後,它看起來是這樣的:

public static Specification<Domain> notificationContactSpec(String contactValue) { 
     return (root, query, cb) -> cb.equal(root.join(Domain_.notification).get(Notification_.contact), contactValue); 
} 

更多元模型生成: https://docs.jboss.org/hibernate/orm/5.0/topical/html/metamodelgen/MetamodelGenerator.html

+0

工作!感謝隊友 – cgval

+0

酷:)考慮使用元模型生成器,它是非常有用的工具 –

+0

同意! :) 再次感謝 – cgval