2012-08-23 69 views
2

我正在爲汽車經銷商開發Web應用程序。我有一個Car類,其中包含一組安全枚舉。使用JPA Criteria API查詢Enum的ElementCollection

public class Car { 
    @Id 
    @GeneratedValue 
    private Long id; 

    @NotNull(message = "{year}") 
    @Min(value = 1950) 
    @Max(value = 2020) 
    @Column(nullable = false) 
    private int year; 

    @NotNull() 
    @Column(nullable = false) 
    private String make; 

    @NotNull() 
    @Column(nullable = false) 
    private String model; 

    @NotNull() 
    @Min(value = 0) 
    @Max(value = 1000000) 
    @Column(nullable = false) 
    private int kilometres; 

    @Column(nullable = false) 
    private int price; 


    @NotNull() 
    @Enumerated(EnumType.STRING) 
    private Gearbox gearbox; 

    @ElementCollection(fetch = FetchType.EAGER) 
    @Enumerated(EnumType.STRING) 
    @CollectionTable(name="SECURITY") 
    @Column(name="TYPE") 
    private Set<Security> securityList = new HashSet<Security>(); 

    @NotNull() 
    @Column(nullable = false) 
    private String description; 

    @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, orphanRemoval = true) 
    private List<Picture> pictureList = new ArrayList<Picture>(); 

    // Getters and setters + help methods.. 

安全枚舉是這樣的:

public enum Security { 

    ABS("abs"), 
    AIRBAG("airbag"), 
    ANTISPIN("antispin"), 
    CENTRAL_LOCKING("centralLocking"), 
    REMOTE_ALARM("remoteAlarm"), 
    FOUR_WHEEL("fourWheel"), 
    PARKING_ASSISTANCE("parkingAssistance"), 
    SERVICE_MANUAL("serviceManual"), 
    STABILITY_CONTROL("stabilityControl"), 
    XENON_LIGHT("xenonLight"); 

    private String label; 

    private Security(String label) { 

    } 

    public String getLabel() { 
     return label; 
    } 
} 

在Web應用程序中,我將創建一個搜索頁面,用戶能夠定義所需的Securitiy零部件和製造商模式(讓現場汽車類)。例如,用戶可能會搜索具有符合「大衆汽車」製造模式的汽車,而安全性至少爲ABS和REMOTE_ALARM。

我的問題是,我不知道如何使用條件API創建查詢。我想它應該開始像:

public List<Car> searchCars(String makePattern, Set<Security> requiredSecuirtySet) { 

     CriteriaBuilder cb = em.getCriteriaBuilder(); 

     CriteriaQuery<Car> cq = cb.createQuery(Car.class); 
     Root<Car> _car = cq.from(Car.class); 


     // Give me some help here please =) 


     return em.createQuery(cq).getResultList(); 
} 

你能幫我嗎?我還有一個Car類的元模型。

此致敬意!

+0

您需要使用where子句。其中car.make =:make等。您還可以在查詢中傳遞集合,以便查詢具有某些安全功能的汽車。 – siebz0r

+0

感謝您的回答!在searchCar中,我傳遞了一組必需的安全枚舉。所以我想這就是你的意思,問題是我不知道如何執行它=( – kungcc

回答

1

感謝siebz0r!

由於您的代碼返回所有具有1個或更多安全性(並非全部)的Cars,即返回所有具有至少包含securityList的子集的安全列表的汽車,所以我修改了您的代碼。

這裏是我的代碼:

public List<Car> searchCars(String makePattern, Set<Security> requiredSecuirtySet) { 

     CriteriaBuilder cb = em.getCriteriaBuilder(); 

     CriteriaQuery<Car> cq = cb.createQuery(Car.class); 
     Root<Car> car = cq.from(Car.class); 

     Predicate criteria = cb.conjunction(); 
     for (Security security : carQueryData.getSecurityCriteria()) { 
      criteria = cb.and(criteria, car.get(Car_.securityList).in(security)); 
     } 
     // Add more predicates, for instance: 
     // for (Equipment equipment : carQueryData.getEquipmentsCriteria()) { 
     // criteria = cb.and(criteria, car.get(Car_.equipmentList).in(equipment)); 
     // } 

     Predicate makePredicate = cb.equal(car.get(Car_.make), makePattern); 

     cq.select(car).where(makePredicate, criteria); 

     return em.createQuery(cq).getResultList(); 
    } 

問候

+0

元模型已添加到代碼段中 – kungcc

4

您可以使用集合作爲參數,所以也許這將工作:

TypedQuery<Car> q = em.createQuery("select c from Car c where c.make = :make and c.securityList in :secutiryList", Car.class); 
q.setParameter("make", makePattern); 
q.setParameter("securityList", requiredSecuirtySet); 

return q.getResultList(); 

我還沒有測試,所以我不知道它會工作。它基於this question 我也沒有使用標準API,所以我不知道如何「翻譯」它。

這裏有一個鏡頭在查詢與標準API:

public List<Car> searchCars(String makePattern, 
     Set<Security> requiredSecuirtySet) 
{ 
    CriteriaBuilder builder = em.getCriteriaBuilder(); 

    CriteriaQuery<Car> query = builder.createQuery(Car.class); 
    Root<Car> car = query.from(Car.class); 
    query.select(car).where(
      builder.equal(car.get("make"), makePattern), 
      car.get("securityList").in(requiredSecuirtySet)); 
    return em.createQuery(query).getResultList(); 
} 
+0

謝謝,這是exaclty我想要的,但與標準API – kungcc

+0

@kungcc我已經做了一個嘗試做使用條件查詢API查詢請參閱我的更新回答 – siebz0r