Я немного сбит с толку при создании критерияQuery с JPA 2.0.
Предварительные требования:
У меня есть графический интерфейс, в котором пользователь может отмечать некоторые флажки (скажем) погодных станций с некоторыми параметрами, такими как температура / ветер / период времени и т. д.
Теперь я хочу настроить queryQuery, чтобы выбрать только выбранные элементы из базы данных sql и вернуть их в виде объекта / карты / списка для создания некоторых моделей данных (это будет использоваться для создания нескольких диаграмм с примерами).
Что у меня есть:
// 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");
}};
критерийBuilder, критерийQuery и класс сопоставления:
// 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}
cq.multiselect()
все еще существует :( - person RonH   schedule 14.09.2011