【问题标题】:How to iterate and dynamically parameterize JPQL queries?如何迭代和动态参数化 JPQL 查询?
【发布时间】:2011-09-22 01:58:26
【问题描述】:

我有一个带有简单 ID 作为 URL 参数的页面。我现在要做的是运行一个查询来返回一些基本上需要迭代的关联实体:我需要为 LEAGUE 游戏、CUP 游戏和 PLAYOFFS 游戏返回一个游戏时间表,因此结果列表必须根据每个迭代。

每个时间表在 GUI 中都有自己的选项卡。对于 RichFaces 选项卡,我已经需要 JSTL c:forEach,所以我“只”需要找到一种方法来为组件(这里是 Seam EntityQuery 子类实例)设置另一个 WHERE 限制。

这里的问题是:如何在迭代期间使用当前实体参数化每个查询?在 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>

这里的问题是你不能简单地在 c:forEach 中调用类似#{rosterScheduleQuery.setCustomRestriction(pa.group.round.subCompetition.competition.name)} 的东西,因为这个表达式只会被评估一次(如果我理解正确的话)。我可能在这里遗漏了要点,因为这都是程序性的。

您通常如何解决迭代和运行时参数化查询(附加 WHERE 条件)?我们始终欢迎最佳做法。

谢谢

编辑:我已经在使用 Facelets,但是 rich:tabPanel 需要使用 JSTL c:forEach。见http://relation.to/11633.lace

【问题讨论】:

  • 你能用 Facelets 代替 JSP 吗?然后您可以使用&lt;ui:repeat&gt; 而不是&lt;c:forEach&gt;,这在这种情况下应该可以工作。不过,我很欣赏改用 Facelets 是一个重大的步骤。
  • 您想要一组动态生成的选项卡面板,每个计划一个?为什么您希望这些都在使用“客户端”开关类型加载页面时生成,而不是在单击选项卡面板时生成?换句话说,“ajax”开关类型是一个选项吗?然后在单击选项卡时运行查询?
  • 是的,我希望每个标签有一个时间表。我需要为每个选项卡(即每个游戏类型)稍微调整查询,所以一般的问题是如何在每次迭代时将一个值放入查询实例中,这实际上只在每个请求中实例化。在查询上设置一些东西似乎不起作用。时间表始终是第一个选项卡中的时间表。也许我错过了什么......

标签: jsf seam iteration el parameterized-query


【解决方案1】:

混合使用 JSP 和 JSF 处理程序并不是一个好主意。您使用的 switchType 等于 client,这意味着它的内容将被预先呈现给客户端,并且在切换过程中不会发生与服务器的交互

好吧,这不是最好的解决方案,但我认为它可以帮助你

<rich:tabPanel value="#{participationTabPanel}">
</rich:tabPanel>

你管理的 bean

@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;
    }

}

【讨论】:

    【解决方案2】:

    JBossEL 允许带参数的方法调用,因此您可以添加一个中间 bean,该 bean 具有一个采用类型并检索结果的方法。基本上用“#{someNewBean.getResults(pa)}”替换“#{rosterScheduleQuery.resultList}”。该 bean 会将查询注入其中,它可以根据需要对其进行参数化。可能没有你想的那么优雅,但我想我会这样做。

    【讨论】:

    • 我得看看这个。谢谢。
    • 我刚刚注意到你说rosterScheduleQuery 已经是一个EntityQuery 子类,所以你不需要我之前说的“中间bean”。您可以将限制方法添加到您的查询类。
    • 我实现了 rosterScheduleQuery.getResultListFor(Participation pa),它通过 return super.getResultList() 返回相同的实体列表,但根本没有没有变化。每个选项卡的时间表始终相同。然后我发现了这个:stackoverflow.com/questions/3170296/…。但是,在 super.getResultList() 之前使用 refresh()、setMaxResults(getMaxResults)、... 或任何其他调用似乎会导致无限循环。浏览器尝试加载页面但不会停止。这让我发疯了。
    猜你喜欢
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-30
    • 2019-12-14
    • 2021-08-10
    相关资源
    最近更新 更多