缓存/优化从数据库加载数据的动态视图

时间:2013-04-26 05:18:57

标签: java jsf caching jsf-2 memcached

我创建了文章复合组件,我几乎在每一页都使用它。此CC从数据库加载数据并将其插入视图中。要使用此CC,我只需要调用<cc:article id="article-id"/>,因此使用起来非常简单。问题是我需要在每个请求中从数据库加载数据,因此它不是最佳解决方案。我想优化它,但我不知道如何。在我写出什么想法之前,我必须解决这个问题,让我们看看cc最重要的部分是什么样的:

这是CC

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" ...>

    <h:body>
        <cc:interface componentType="articleFacesComponent">
            <cc:attribute name="articleId" required="true" />
            <cc:attribute name="editable" type="boolean" default="false" required="false" />
            <cc:attribute name="styleClass" default="article" required="false" />
        </cc:interface>
        <cc:implementation>
            <h:outputStylesheet library="cc" name="js/article.css" />
            <div class="#{cc.attrs.styleClass}">
                ...
                    <!-- here I load article from FacesComponent -->
                    <h:outputText value="#{cc.article.text}" escape="false" />
                ...
            </div>
        </cc:implementation>
    </h:body>
</html>

这是cc

使用的FacesComponent
import entity.Article;
import javax.faces.component.FacesComponent;
import javax.faces.component.UINamingContainer;
import javax.persistence.EntityManager;
import service.DatabaseManager;

@FacesComponent("articleFacesComponent")
public class ArticleFacesComponent extends UINamingContainer {

    private Article article;
    private EntityManager em;

    public Article getArticle() {
        if (article==null) {
            init();
        }
        return article;
    }

    private void init() {
        em = DatabaseManager.getInstance().em();
        Object idObj = getAttributes().get("articleId");
        if (idObj != null) {
            String id = String.valueOf(idObj);
            if (id != null) {
                article = em.find(Article.class, id);
                if (article == null) {
                    article = new Article(id);
                }
            }
        }
    }

}

首先,我想写一下这个解决方案的问题:

  1. 我需要在每次请求时从数据库加载数据
  2. FacesComponent看起来很难看,因为我无法将托管bean注入其中,甚至无法调用PostContruct。
  3. getArticle()我需要每次都调用init(),因为cc属性在构造函数中不可见。
  4. 它应该如何运作?

    1. FacesComponent不应从数据库加载数据。
    2. 我应该能够将托管bean注入FacesComponent。有可能吗?
    3. 我应该可以在FacesComponent中调用PostContruct。
    4. 我有什么想法可以解决这个问题?

      1. 我认为我可以创建线程安全类,它将从数据库加载数据并将其存储在List中。这个解决方案的优点是我只会从db加载数据一次,但缺点是我需要将所有文章保存在内存中。现在我有大约30篇文章,所以它可以以这种方式工作,但将来可能会有300或3000篇文章,所以它会浪费内存。
      2. 缓存视图。创建解决方案以创建静态视图并将它们存储在缓存目录中,从中加载它们。也许JSF为动态视图提供了一些缓存解决方案?

1 个答案:

答案 0 :(得分:1)

关于具体问题,JSF实用程序库OmniFaces有一个<o:cache>组件,它允许您在会话中缓存组件生成的HTML输出,甚至可以在特定键上缓存应用程序范围确定的时期。另请参阅showcase page