Как перебирать и динамически параметризировать JPQL-запросы?
У меня есть страница с простым идентификатором в качестве параметра URL. Что я делаю сейчас, так это запускаю запрос, чтобы вернуть количество связанных сущностей, которые в основном должны пройти итерацию: мне нужно, чтобы график игр возвращался для игр LEAGUE, CUP и PLAYOFFS, поэтому списки результатов должны отличаться в зависимости от итерация.
Каждое из этих расписаний получает свою вкладку в графическом интерфейсе. Мне уже нужен JSTL c:forEach для вкладок RichFaces, поэтому мне "только" нужно найти способ установить другое ограничение WHERE для компонента (здесь экземпляр подкласса Seam EntityQuery).
Проблема в следующем: как вы параметризуете каждый запрос с текущей сущностью во время итерации? Как это лучше всего сделать в Seam/JBoss EL? Как получить другое ограничение или два в экземпляре EntityQuery во время итерации?
Вот код JSF, который я использую:
<rich:tabPanel>
<c:forEach items="#{participationListQuery.resultList}" var="pa">
<rich:tab label="#{...}" switchType="client">
<h:form>
<rich:dataTable id="schedule-scores"
value="#{rosterScheduleQuery.resultList}"
var="sgl"
width="100%"
rows="20">
...
</rich:dataTable>
</h:form>
</rich:tab>
</c:forEach>
</rich:tabPanel>
Проблема в том, что вы не можете просто назвать что-то вроде #{rosterScheduleQuery.setCustomRestriction(pa.group.round.subCompetition.competition.name)}
в c: forEach, так как это выражение будет оцениваться только один раз (если я правильно понимаю). Я мог бы здесь упустить общий смысл, поскольку все это довольно процедурно.
Как вы обычно решаете итеративные и параметризованные запросы во время выполнения (дополнительные условия WHERE)? Лучшие практики всегда приветствуются.
Спасибо
Редактировать: я уже использую Facelets, но rich:tabPanel требует использования JSTL c:forEach. См. http://relation.to/11633.lace.
2 ответа
JBossEL разрешает вызовы методов с параметрами, так что вы можете добавить промежуточный компонент, имеющий метод, который принимает тип и получает результаты. В основном замените "#{rosterScheduleQuery.resultList}" на "#{someNewBean.getResults(pa)}". В этот боб будет вставлен запрос, который он может параметризировать по мере необходимости. Возможно, не так элегантно, как хотелось бы, но я думаю, что именно так я и сделаю.
Не рекомендуется смешивать обработчики JSP и JSF. Вы используете switchType равный клиенту, что означает, что его содержимое будет передано клиенту, и во время переключения взаимодействие с сервером не произойдет.
Ну, это не может быть лучшим решением, но я думаю, что это может помочь вам
<rich:tabPanel value="#{participationTabPanel}">
</rich:tabPanel>
Вы управляли бобом
@Name
public class ParticipationManagedForm {
private @In EntityQuery<Participation> participationListQuery;
@Factory(value="participationTabPanel", scope=ScopeType.EVENT)
public HtmlTabPanel getParticipationTabPanel() {
HtmlTabPanel panel = new HtmlTabPanel();
for(List<Participation> participationList: participationListQuery.getResultList()) {
HtmlTab htmlTab = new HtmlTab();
// Set up htmlTab right here
panel.getChildren().add(htmlTab);
}
return panel;
}
}