4

私は自動車ディーラー向けの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クラスのmakeフィールド)を定義できる検索ページを作成します。たとえば、ユーザーは「フォルクスワーゲン」に準拠したメーカーパターンと、少なくとも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クラスのメタモデルもあります。

よろしくお願いいたします。

4

2 に答える 2

6

コレクションをパラメーターとして使用できるため、これでうまくいく可能性があります。

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

私はこれをテストしていないので、うまくいくかどうかはわかりません。この質問に基づいています。また、criteria 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();
}
于 2012-08-24T14:40:59.713 に答える
1

ありがとうsiebz0r!

コードが1つ以上のセキュリティ(すべてではない)を持つすべての車を返すため、つまり、少なくともsecurityListのサブセットを含む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();
    }

よろしくお願いします

于 2012-08-27T19:59:39.507 に答える