2012-08-23 71 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