更新二:好的,我设法缩小了范围。
我有一个带有数据表的页面,具有排序和过滤功能,两者都发生在数据库中。换句话说,我不使用我使用的 rich:datatable 的嵌入式功能,而是让 DB 来完成工作。
我与请求范围豆子。唯一的会话范围 bean 包含我的界面的排序和过滤。
对每列的过滤都绑定到特定的会话 bean 字段。因此,它实际上是在更新模型值阶段更新的。
排序需要我的一些逻辑,因此我调用某种方法来为会话 bean 设置正确的值。这是在调用应用程序阶段执行的。
因此,任何更改都会在页面实际呈现的渲染响应阶段进行。
问题是我页面中的 JSF 数据表和 datascroller 调用backingBean.getDataModel()
从数据库中获取数据和dataModel.getRowCount()
(我已经实现了调用运行单独查询的方法)also在此期间应用请求值阶段。这两个查询也发生在渲染响应阶段,这是唯一一个更改全部到位且查询将正常运行的阶段。
这意味着要在执行过滤或排序后显示页面,会发生双倍的查询。
我只想执行排序和过滤,仅执行所需的查询,仅此而已。
有什么建议么?
应用请求值阶段期间的 getter 调用是强制性的,因为 JSF 需要知道最初显示了哪些输入值,以便最终可以在下一阶段(如果适用)进行任何验证和/或调用任何 valuechangelistener。还必须找出在任何行中按下/单击了哪个按钮/链接,以便它知道在调用操作阶段要调用哪个 bean 操作。
但是,如果您没有任何要验证/值更改检查的输入字段,也没有任何行中的任何按钮/链接,那么我可以想象应用请求值阶段期间的查询在您看来完全是多余的。
不幸的是,您无法完全禁用它。从技术上讲,唯一的方法是将数据 bean 放入会话范围中,并仅在 bean 的构造函数和 bean 操作方法中执行昂贵的 SQL 查询(以及数据模型的刷新),以便仅在 bean 运行期间调用它。构造(对于第一个视图)和 bean 的操作方法期间(在新的排序/过滤器/任何请求期间)。然而,缺点是数据模型中的任何更改都会反映在最终用户在同一会话中打开的所有窗口/选项卡中,这可能会导致“wtf?”最终用户的体验。
现在,Tomahawk 是第一个针对此问题提供了很好的解决方法的解决方案。preserveDataModel
属性为<t:dataTable>
,这基本上将数据模型放入特定于请求的组件树中(该组件树又已经存储在会话范围中或客户端的隐藏输入字段中,具体取决于您如何配置面孔中视图状态的存储位置)配置)。 RichFaces 没有这样的直接解决方案,但是<a4j:keepAlive>
基本上是一样的。它只会影响“整个”bean,因此如果您的数据 bean 不仅仅包含数据模型,您可能会考虑重构它。您应该记住将 bean 设计为会话范围的 bean。
如果数据模型变大,那么我可以想象这会影响服务器内存,但如果您只存储viewable内存中数据模型的一部分(因此不是entire数据模型,包括所有其他页面)。看看它是否超过在单个 HTTP 请求期间触发两次 SQL 查询的成本。
希望这可以帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)