построение запроса критериев с jpa 2.0 с использованием динамического списка

Я немного сбит с толку при создании критерия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}

person RonH    schedule 14.09.2011    source источник
comment
Я вижу правку в середине вашего вопроса. Этот вопрос теперь устарел? Если это так, удалите вопрос или ответьте на него самостоятельно, так как это сбивает с толку других пользователей, которые находят ваш отредактированный (и отвеченный) вопрос ...   -  person Lukas Eder    schedule 14.09.2011
comment
к сожалению, на вопрос нет ответа :(. Я только кое-что исправил, но основная проблема с динамическим заполнением cq.multiselect() все еще существует :(   -  person RonH    schedule 14.09.2011
comment
Ладно, я этого не осознавал ... На первый взгляд это выглядело как основная проблема   -  person Lukas Eder    schedule 14.09.2011
comment
Можете ли вы ответить на свой вопрос так, чтобы это помогло другим? Если да, то можете выбрать свой как правильный ответ. Это может показаться странным, но это предпочтительный способ справляться с подобными ситуациями.   -  person    schedule 14.09.2011


Ответы (1)


Что ж, иногда это слишком банально, чтобы быть правдой -.-

Один из способов заполнить cq.multiselect () моим динамическим списком - просто создать список выборок и передать его моему запросу множественного выбора.

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

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

cq.multiselect(s);

легко, но, возможно, у кого-то такие же проблемы с этим :)
и даже если нет, рассмотрите это как пример для критерияQuery;)

person RonH    schedule 15.09.2011
comment
Вау, удивительно, что я нашел это ... Спасибо, это было полезно. - person AFP_555; 18.12.2016