3

JPA 2.0 で criteriaQuery を作成しているときに少し混乱しています。

前提条件:
私は、温度/風/期間/などのようないくつかのオプションを使用して、ユーザーが (たとえば) 気象観測所のいくつかのチェックボックスをマークできる GUI を持っています...

ここで、SQL データベースから選択したアイテムだけを選択し、それをオブジェクト/マップ/リストとして返して DataModel を構築するように criteriaQuery を設定したいと考えています (これは、いくつかの素数チャートを生成するために使用されます)。

私がこれまでに持っているもの:

// for presentation purposes just this mockup-data
Calendar start = new GregorianCalendar(2011, Calendar.APRIL, 1);
Calendar end = new GregorianCalendar(2011, Calendar.MAY, 1);
List<String> selectedStations = new LinkedList<String>() {{
    add("PS1");
    add("PS2");
    add("PS3");
}};
Map<String, Object selectedOptions = new LinkedHashMap<String, Object>() {{
    put("opt1","val1");
    put("opt2","val2");
    put("opt3","val3");
}};
List<String> sel = new LinkedList<String>() {{
    add("selOpt1");
    add("selOpt2");
    add("selOpt3");
}};

criteriaBuilder、criteriaQuery、およびマッピング クラス:

// go for the criteriaBuilder
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<StationItem> r = cq.from(StationItem.class);

述部のセットアップ:

// ... where (name="PS1" or name="PS2" or name="PS3") ...
Predicate p1 = cb.disjunction();
for (String s : selectedStations) {
    p1 = cb.or(p1, cb.equal(r.get("name").as(String.class), s));
}
Predicate p2 = cb.between(r.get("fetchDate").as(Date.class),
    start.getTime(), end.getTime());
Predicate p3 = cb.conjunction();
for (Map.Entry<String, Object> param : selectedOptions.entrySet())
    p3 = cb.and(p3, cb.equal(r.get(param.getKey()), param.getValue()));

そして、クエリを実行して結果を取得する最後のステップ:

この時点で、複数選択基準を選択内容で満たすための最良のアプローチが何であるかはわかりません。List sel から cq.multiselect() にすべてのアイテム/選択を動的に挿入したいと思います...
どんなアイデアでも大歓迎です!

// This is working but static :(
cq.multiselect(r.get(sel.get(0)), r.get(sel.get(1)), r.get(sel.get(2)));

// i would prefer to have something like 
for (int i=0;i<sel.size();i++) {
    cq.multiselect().add(r.get(sel.get(i)));
}

私のWHERE句を連結してクエリを実行する:

cq.where(cb.and(p1,p2,p3));

List<Tuple> res = em.createQuery(cq).getResultList();
for (Tuple t : res) {
    // do something ...
};
return <something useful>

私が達成したいことを要約するために疑似SQLクエリに従ってください:

SELECT {items from List<String> sel}
FROM MyStationDatabase
WHERE (name = selectedStation.get(0) OR ... OR name = selectedStation.get(last))
    AND {items from Map<String,Object> selectedOptions}
4

1 に答える 1

4

まあ、時にはそれは真実であるにはあまりにも些細なことです -.-

動的リストで cq.multiselect() を埋める 1 つの方法は、選択リストを作成し、これを multiselect-query に渡すことです。

List<Selection<?>> s = new LinkedList<Selection<?>>();

for (String item : sel) {
    s.add(r.get(item));
}

cq.multiselect(s);

簡単ですが、誰かがこれに同じ苦労をしているかもしれません:)
そうでない場合でも、criteriaQueryの例として参照してください;)

于 2011-09-15T07:30:30.740 に答える