请求范围的bean和数据模型初始化? [英] Request-scoped beans and datamodel initialization?

查看:117
本文介绍了请求范围的bean和数据模型初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新II: 好的,我设法将其范围缩小了.

UPDATE II: OK, I managed to narrow it down a little.

我有一个带有数据表的页面,该数据表具有排序和过滤功能,两者均在数据库中进行.换句话说,我没有使用我使用的rich:datatable的嵌入式功能,而是让DB来完成工作.

I have a page with a datatable with sorting and filtering functionalities, both taking place in the DB. In other words, I do not use the embedded functionality of the rich:datatable I use, but rather let the DB do the work.

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

I work with request-scoped beans. The only session-scoped beans contain the sorting and filtering of my interface.

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

Filtering for each column is bound to the certain session bean fields. As such, it is actually updated during the Update Model Values phase.

排序从我的角度来说需要一些逻辑,因此我调用某种方法来为会话bean设置正确的值.这是在调用应用程序"阶段执行的.

Sorting required some logic from my part, so I invoke a certain method to set the correct values to the session bean. This is performed during the Invoke Application phase.

因此,在页面实际呈现的渲染响应"阶段,所有更改都已就绪.

So, any changes are in place during the Render Response phase, where the page actually renders.

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

The problem is that the JSF datatable and datascroller in my page call the backingBean.getDataModel() that fetch the data from the DB and the dataModel.getRowCount() (which I have implemented to invoke a method that runs a separate query) also during the Apply Request Values phase. These two queries take also place during the Render Response Phase, which is the only phase where the changes are all in place, and the query will run normally.

这意味着要在执行过滤或排序后显示一个页面,就会发生两倍数量的查询.

This means that to show a page after I perform filtering or sorting, the double number of queries take place.

我只想执行排序查询和过滤操作,而不再执行其他操作.

I want to perform sorting and filtering only performing the required queries and no more.

有什么建议吗?

推荐答案

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

The getter call during apply request values phase is mandatory because JSF needs to know which input values were initially shown so that it can eventually do any validation and/or call any valuechangelisteners in the next phase where applicable. It is also mandatory to find out which button/link was pressed/clicked in any of the rows so that it knows which bean action to call in the invoke action phase.

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

But if you don't have any input fields which are to be validated/valuechange-checked nor any buttons/links in any of the rows, then I can imagine that the query during apply request values phase is in your eye completely superfluous.

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

Unfortunately, you can't completely disable it. Technically, the only resort to that is putting the data bean in the session scope and do the expensive SQL query (and refresh of datamodel) only in the constructor of the bean and in the bean action method, so that it only get invoked during bean's construction (for 1st view) and during bean's action method (during a new sort/filter/whatever request). The disadvantage is however that any changes in the datamodel are reflected in all windows/tabs the enduser has open in the same session, which might cause "wtf?" experiences for the enduser.

现在,战斧"是第一个具有不错的变通办法的,它具有<t:dataTable>preserveDataModel属性的风格,该属性基本上将数据模型放入特定于请求的组件树中(该树已存储在特定于请求的组件树中)会话范围或客户端的隐藏输入字段中,具体取决于您如何在faces-config中配置视图状态的存储位置). RichFaces没有类似的直接解决方案,但是<a4j:keepAlive>基本上是相同的.它只会影响整个" bean,因此,如果您的数据bean所包含的不仅是数据模型,则可以考虑对其进行重构.您应该牢记将bean设计为会话范围的bean.

Now, Tomahawk was the first which has a nice workaround for this in flavor of the preserveDataModel attribute for the <t:dataTable>, which basically puts the datamodel in the request-specific component tree (which in turn is already stored in the session scope or in a hidden input field in the client side, depending on how you configured the store location of the view state in faces-config). RichFaces doesn't have a direct solution like that, but the <a4j:keepAlive> does basically the same. It would only affect the "whole" bean, thus if your data bean contains more than only the datamodel, you might consider to refactor it. You should keep in mind to design the bean as if it is a session scoped bean.

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

If the datamodel gets large, then I can imagine that this impacts the server memory, but this shouldn't really harm that much if you only stores the viewable part of the datamodel in memory (and thus not the entire datamodel, including all the other pages). See if it outweighs the cost of firing double SQL queries during a single HTTP request.

希望这会有所帮助.

这篇关于请求范围的bean和数据模型初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆