在JSF的存取/ getter方法内的业务逻辑(Business logic inside an a

2019-10-19 17:59发布

我在MySQL数据库三个表。

  • 类别(从这个问题除外)
  • sub_category
  • 产品

这些表之间的关系是直观的 - 一个一对多在它们出现的顺序。


我通过列表迭代SubCategoryList<SubCategory>使用<p:dataGrid>如下。

<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>

没有与值相关联的属性参数化getter方法</p:carousel> featuredProductManagedBean.getProducts(row.subCatId)

该方法被称为几次造成昂贵的商业服务(S)被调用多次。

托管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)以防止多次调用该服务的方法。 这是否有条件的检查进行了正确的事情? 它有一定的副作用?

这个答案保持一个Map ,但保持一个Map为大型数据源是昂贵的。

有没有以防止多次执行这样的商业逻辑以精确的方式?

Answer 1:

我建议当前加载的产品存放subCategoryMap ,他们由懒惰的模型加载刚过<p:dataGrid> 。 地图上永远不会太大,因为你会在每次调用清空load的方法:

@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 Map<Long, Product> productsBySubCategory = new HashMap<>(); //Getter only.
    private static final long serialVersionUID = 1L;

    @Override
    public List<SubCategory> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters)
    {
        int rowCount = service.rowCount().intValue();
        setRowCount(rowCount);

        List<SubCategory> subCategories = service.getList(first, pageSize);
        productsBySubCategory.clear();
        for (SubCategory sc : subCategories) 
        {
            productsBySubCategory.put(sc.getSubCatId(), service.getProductList(sc.getSubCatId());
        }
        return subCategories;
    }
}

并获得直接的Map从EL:

<p:carousel value="#{featuredProductManagedBean.productsBySubCategory[row.subCatId]}" />

请注意,你并不需要所有的样板,检查页边界,并设置页面大小。



文章来源: Business logic inside an accessor / getter method in JSF