4

更新二: 好的,我设法缩小了一点。

我有一个带有排序和过滤功能的数据表的页面,两者都发生在数据库中。换句话说,我不使用我使用的 rich:datatable 的嵌入式功能,而是让 DB 来完成这项工作。

我使用请求范围的bean。唯一的会话范围 bean 包含我的界面的排序和过滤。

每列的过滤都绑定到特定的会话 bean 字段。因此,它实际上是在更新模型值阶段更新的。

排序需要我的一些逻辑,所以我调用了某种方法来为会话 bean 设置正确的值。这是在调用应用程序阶段执行的。

因此,任何更改都在页面实际呈现的呈现响应阶段进行。

问题是我页面中的 JSF 数据表和 datascroller 在应用请求值阶段backingBean.getDataModel()调用了从数据库中获取数据的 和dataModel.getRowCount()(我已经实现调用运行单独查询的方法) 。这两个查询也发生在渲染响应阶段,这是唯一一个更改全部到位的阶段,查询将正常运行。

这意味着在我执行过滤或排序后显示页面,会发生双倍的查询。

我想执行排序和过滤只执行所需的查询,而不是更多。

有什么建议么?

4

1 回答 1

1

在应用请求值阶段的 getter 调用是强制性的,因为 JSF 需要知道最初显示了哪些输入值,以便它最终可以进行任何验证和/或在适用的下一阶段调用任何 valuechangelisteners。还必须找出在任何行中按下/单击了哪个按钮/链接,以便它知道在调用操作阶段要调用哪个 bean 操作。

但是,如果您没有任何要验证/值更改检查的输入字段,也没有任何行中的任何按钮/链接,那么我可以想象应用请求值阶段期间的查询在您看来完全是多余的。

不幸的是,您不能完全禁用它。从技术上讲,唯一的办法是将数据 bean 放在会话范围内,并仅在 bean 的构造函数和 bean 操作方法中执行昂贵的 SQL 查询(和数据模型的刷新),以便它只在 bean 的过程中被调用构造(对于第一个视图)和 bean 的操作方法期间(在新的排序/过滤/任何请求期间)。然而,缺点是数据模型中的任何更改都会反映在最终用户在同一会话中打开的所有窗口/选项卡中,这可能会导致“wtf?” 最终用户的体验。

现在,Tomahawk 是第一个有一个很好的解决方法来解决这个问题preserveDataModel<t:dataTable>.在客户端,取决于您在 faces-config 中配置视图状态的存储位置的方式)。RichFaces 没有这样的直接解决方案,但<a4j:keepAlive>基本相同。它只会影响“整个”bean,因此如果您的数据 bean 包含的不仅仅是数据模型,您可能会考虑重构它。您应该记住将 bean 设计为好像它是会话范围的 bean。

如果数据模型变大,那么我可以想象这会影响服务器内存,但是如果您只将数据模型的可视部分存储在内存中(因此不是整个数据模型,包括所有其他页)。看看它是否超过了在单个 HTTP 请求期间触发双 SQL 查询的成本。

希望这可以帮助。

于 2010-03-03T20:11:07.147 回答