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

时间:2020-12-27 20:10:36

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

更新二:好的,我把范围缩小了一点。

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.

我有一个具有排序和过滤功能的数据表的页面,它们都发生在DB中。换句话说,我不使用rich:datatable的嵌入功能,而是让DB来执行。

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

我使用请求范围内的bean。惟一的会话作用域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.

排序需要我的部分提供一些逻辑,因此我调用了一个特定的方法来设置会话bean的正确值。这在调用应用程序阶段执行。

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

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

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.

问题是,我的页面中的JSF datatable和datascroller调用backingBean.getDataModel(),该函数从DB和dataModel.getRowCount()(我实现该函数是为了调用一个运行单独查询的方法)获取数据。这两个查询也发生在呈现响应阶段,这是惟一一个更改都到位的阶段,查询将正常运行。

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.

我只想执行排序和过滤,只执行所需的查询,仅此而已。

Any suggestions?

有什么建议吗?

1 个解决方案

#1


1  

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.

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

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.

但是,如果您没有任何要验证/valuechange-checked的输入字段,也没有任何行中的任何按钮/链接,那么我可以想象,在apply request值阶段的查询完全是多余的。

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.

不幸的是,你不能完全禁用它。技术上,唯一的手段是将会话bean的数据范围和做昂贵的SQL查询datamodel(刷新)只在构造函数中bean的bean动作方法,所以它只能在调用bean的建设期间(1日视图)和bean的操作方法(在新型/过滤器/无论请求)。但是,缺点是,datamodel中的任何更改都反映在enduser在同一个会话中打开的所有窗口/选项卡中,这可能会导致enduser的“wtf?”体验。

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.

现在,战斧是第一,有一个很好的解决了这个味道preserveDataModel属性的< > t:dataTable,基本上把datamodel在特定组件树(进而已经存储在会话范围或在客户端一个隐藏的输入字段,这取决于你如何配置的存储位置在faces-config视图状态)。RichFaces并没有这样的直接解决方案,但是 基本上是一样的。它只会影响“整个”bean,因此,如果您的数据bean包含的数据模型不止一个,您可以考虑重构它。您应该记住设计bean,就好像它是一个会话范围bean。

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.

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

Hope this helps.

希望这个有帮助。

#1


1  

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.

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

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.

但是,如果您没有任何要验证/valuechange-checked的输入字段,也没有任何行中的任何按钮/链接,那么我可以想象,在apply request值阶段的查询完全是多余的。

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.

不幸的是,你不能完全禁用它。技术上,唯一的手段是将会话bean的数据范围和做昂贵的SQL查询datamodel(刷新)只在构造函数中bean的bean动作方法,所以它只能在调用bean的建设期间(1日视图)和bean的操作方法(在新型/过滤器/无论请求)。但是,缺点是,datamodel中的任何更改都反映在enduser在同一个会话中打开的所有窗口/选项卡中,这可能会导致enduser的“wtf?”体验。

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.

现在,战斧是第一,有一个很好的解决了这个味道preserveDataModel属性的< > t:dataTable,基本上把datamodel在特定组件树(进而已经存储在会话范围或在客户端一个隐藏的输入字段,这取决于你如何配置的存储位置在faces-config视图状态)。RichFaces并没有这样的直接解决方案,但是 基本上是一样的。它只会影响“整个”bean,因此,如果您的数据bean包含的数据模型不止一个,您可以考虑重构它。您应该记住设计bean,就好像它是一个会话范围bean。

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.

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

Hope this helps.

希望这个有帮助。