Как перебирать и динамически параметризировать 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;
    }

}
Другие вопросы по тегам