繁体   English   中英

请求范围的bean和数据模型初始化?

[英]Request-scoped beans and datamodel initialization?

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

我有一个带有数据表的页面,其中包含排序和过滤功能,这些都在数据库中进行。 换句话说,我不使用rich的嵌入式功能:我使用的数据表,而是让数据库完成工作。

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

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

排序需要我的部分逻辑,所以我调用某个方法来为会话bean设置正确的值。 这在Invoke Application阶段执行。

因此,在渲染响应阶段,页面实际呈现的任何更改都已到位。

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

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

我想执行排序和过滤只执行所需的查询而不再执行。

有什么建议?

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

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

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

现在,Tomahawk是第一个对<t:dataTable>preserveDataModel属性有一个很好的解决方法,它基本上将数据模型放在特定于请求的组件树中(而后者又存储在会话范围中)或者在客户端的隐藏输入字段中,具体取决于您在faces-config中配置视图状态的存储位置的方式。 RichFaces没有这样的直接解决方案,但<a4j:keepAlive>基本相同。 它只会影响“整个”bean,因此如果您的数据bean包含的不仅仅是数据模型,您可以考虑重构它。 您应该记住将bean设计为会话作用域bean。

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

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM