我在MySQL数据库中有三个表。JSF中访问器/ getter方法内的业务逻辑
- 类别(从这个问题除外)
- sub_category
- 产物
这些表之间的关系是直观的 - 一个一对多以它们出现的顺序。
我使用<p:dataGrid>
如下迭代通过SubCategory
列表,List<SubCategory>
。
<p:dataGrid var="row" value="#{featuredProductManagedBean}" rows="4" first="0" columns="1" rowIndexVar="rowIndex" paginator="true" paginatorAlwaysVisible="false" pageLinks="10" lazy="true" rowsPerPageTemplate="5,10,15">
<h:panelGrid columns="1" style="width:100%;">
<p:carousel value="#{featuredProductManagedBean.getProducts(row.subCatId)}" var="prodRow" numVisible="4" pageLinks="5" headerText="#{row.subCatName}" style="text-align: left;">
<!--Display product image in <p:graphicImage>-->
</p:carousel>
<h:outputLink rendered="#{featuredProductManagedBean.count gt 4}" value="xxx">View More</h:outputLink>
</h:panelGrid>
<p:ajax event="page" onstart="PF('blockDataPanelUIWidget').block()" oncomplete="PF('blockDataPanelUIWidget').unblock()"/>
</p:dataGrid>
有与</p:carousel>
featuredProductManagedBean.getProducts(row.subCatId)
值属性相关联的参数获取方法。
该方法被多次调用导致昂贵的业务服务被多次调用。
管理bean:
@ManagedBean
@ViewScoped
public final class FeaturedProductManagedBean extends LazyDataModel<SubCategory> implements Serializable
{
@EJB
private final FeaturedProductBeanLocal service=null;
private Product selectedProduct; //Getter and setter.
private Long count; //Getter and setter.
private static final long serialVersionUID = 1L;
public FeaturedProductManagedBean() {}
public List<Product>getProducts(Long subCatId)
{
List<Product>products=null;
if(FacesContext.getCurrentInstance().getCurrentPhaseId().getOrdinal()==6)
{
setCount(service.countProducts(subCatId));
products=service.getProductList(subCatId);
}
return products;
}
@Override
public List<SubCategory> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters)
{
int rowCount = service.rowCount().intValue();
setRowCount(rowCount);
if(pageSize<=0)
{
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_FATAL, Utility.getMessage("faces.message.error"), Utility.getMessage("pageSize.error.message"));
FacesContext.getCurrentInstance().addMessage(null, message);
return Collections.emptyList();
}
else if(first>=pageSize&&rowCount<=Utility.currentPage(first, pageSize)*pageSize-pageSize) {
first-=pageSize;
}
setPageSize(pageSize);
return service.getList(first, pageSize);
}
}
无论@PostConstruct
不懒加载可以在这里使用。目前我已经进行了条件检查if(FacesContext.getCurrentInstance().getCurrentPhaseId().getOrdinal()==6)
以防止多次调用服务方法。这个条件检查是否执行正确的事情?它有一些副作用吗?
This答案维持Map
,但对于大型数据源维护Map
是昂贵的。
是否有一种精确的方法来防止这种业务逻辑被多次执行?
为了防止多次执行业务逻辑,您应将其移出getter并置于PostConstruct方法中。目前还不清楚你为什么说你不能。 – perissf
单击commandButton时可能出现多次[Primefaces dataTable调用方法。为什么?](http://stackoverflow.com/questions/22662276/primefaces-datatable-call-method-multiple-times-when-click-commandbutton-why) –
因为它大概不可能使用[criteria/JPQL]( http://stackoverflow.com/q/22523074/1391249),@perissf – Tiny