我创建了文章复合组件,我几乎在每一页都使用它。此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
使用的FacesComponentimport 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);
}
}
}
}
}
首先,我想写一下这个解决方案的问题:
getArticle()
我需要每次都调用init()
,因为cc属性在构造函数中不可见。它应该如何运作?
我有什么想法可以解决这个问题?
List
中。这个解决方案的优点是我只会从db加载数据一次,但缺点是我需要将所有文章保存在内存中。现在我有大约30篇文章,所以它可以以这种方式工作,但将来可能会有300或3000篇文章,所以它会浪费内存。答案 0 :(得分:1)
关于具体问题,JSF实用程序库OmniFaces有一个<o:cache>
组件,它允许您在会话中缓存组件生成的HTML输出,甚至可以在特定键上缓存应用程序范围确定的时期。另请参阅showcase page。