【问题标题】:Query ElementCollection of Enum by using JPA Criteria API使用 JPA Criteria API 查询 Enum 的 ElementCollection
【发布时间】:2012-08-19 00:09:35
【问题描述】:

我正在为汽车经销商开发一个 Web 应用程序。我有一个 Car 类,其字段包含一组安全枚举。

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 部件和制造商模式(在 Car 类中创建字段)。例如,用户可能会搜索具有根据“大众”和安全性至少具有 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 类的元模型。

提前致以最诚挚的问候和感谢!

【问题讨论】:

  • 您需要使用 where 子句。其中 car.make = :make 等。您还可以在查询中传递集合,以便查询具有某些安全功能的汽车。
  • 感谢您的回答!在 searchCar 中,我传递了一组所需的安全枚举。所以我想这就是你的意思,问题是我不知道如何执行它=(

标签: java jpa jpa-2.0 criteria-api


【解决方案1】:

您可以使用集合作为参数,所以也许这会起作用:

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();
}

【讨论】:

  • 谢谢,这正是我想要的,但使用标准 API。
  • @kungcc 我已经尝试使用条件查询 API 进行查询。请查看我的更新答案。
【解决方案2】:

谢谢siebz0r!

我稍微修改了您的代码,因为您的代码返回所有具有 1 个或多个安全性(而不是全部)的汽车,即返回所有具有至少包含安全列表子集的安全列表的汽车。

这是我的代码:

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();
    }

最好的问候

【讨论】:

  • 在 sn-p 中添加了元模型
猜你喜欢
  • 2020-07-04
  • 2013-01-21
  • 2018-01-13
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 2016-06-25
相关资源
最近更新 更多