2013-04-26 81 views
1

我創建了幾乎在每個頁面中使用的文章組合組件。該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屬性在構造函數中不可見。

它應該如何工作?

  1. FacesComponent不應該從數據庫加載數據。
  2. 我應該可以將管理bean注入到FacesComponent中。可能嗎?
  3. 我應該可以在FacesComponent中調用PostContruct。

我有什麼想法解決了這個問題?

  1. 我認爲我可以創建線程安全類,它將從數據庫加載數據並將其存儲在List中。這個解決方案的優點是我只會從db加載數據一次,但缺點是我需要將所有文章保存在內存中。現在我有大約30篇文章,所以它可以這樣工作,但將來可能會有300或3000篇文章,因此會浪費內存。
  2. 緩存視圖。創建解決方案以創建靜態視圖並將其存儲在緩存目錄中,以便從中加載它們。也許JSF爲動態視圖獲得了一些緩存解決方案?

回答

1

至於具體問題,JSF工具庫OmniFaces<o:cache>組件,它允許你緩存上的規定期間內的特定鍵的會話甚至是應用範圍的組件生成的HTML輸出。另請參閱showcase page

+0

謝謝。作爲一種快速響應,如果它可以與從數據庫加載的數據一起使用,你可以編寫嗎 – pepuch 2013-04-26 12:03:09

+0

輸出源無關緊要。這都是關於組件的輸出。你只需要改變你的組件,就像你在'encodeBegin()'方法中實現邏輯而不是構造函數一樣。 – BalusC 2013-04-26 12:04:19