2012-11-13 43 views
5

這可能是一種架構問題,但仍然必須具有「最佳實踐解決方案」或公認的標準。使用jsf會話作用域管理bean來表示靜態分層數據

我在談論某種需要在網站上顯示的靜態數據,如產品目錄,菜單和菜單項目列表,麪包屑塊列表等。使用任何標準CMS時,此選項可用假設。

但我想爲這個問題使用純粹的JSF解決方案。

因此,要回到這個問題,我乾的闡述基於以下原則:

  1. 數據不應該在小面被硬編碼,因此我用的數據庫在下面持有的價值觀,像DB腳本(MYSQL在我的情況):

    CREATE TABLE CatalogueGroup (
        CatalogueGroupName VARCHAR(100) NOT NULL PRIMARY KEY, 
        URLPath VARCHAR(200) NOT NULL, 
        ParentGroupName VARCHAR(100) DEFAULT NULL, 
        FOREIGN KEY (ParentGroupName) REFERENCES CatalogueGroup(CatalogueGroupName) ON UPDATE CASCADE ON DELETE SET NULL 
    )ENGINE=InnoDB DEFAULT CHARSET=utf8; 
    
  2. 我會那麼喜歡用實體類的@ManagedBean舉行,並在視圖中顯示出來,就像

    public class CatalogueGroup implements Serializable { 
        private String catalogueGroupName; 
        private List<CatalogueGroup> children = new ArrayList<CatalogueGroup>(); 
        private CatalogueGroup parentGroup; 
        //other stuff of this bean 
    } 
    
    @ManagedBean 
    @SessionScoped 
    public class CatalogueBean implements Serializable { 
        private CatalogueGroup catalogue;//loaded via CatalogueGroupDAO with condition parentGroup == null 
        //other stuff of this bean 
    } 
    
    //snippet of xhtml view for a two-level catalogue 
    <ul><h:outputText value="#{catalogueBean.catalogue.catalogueGroupName}" /> 
        <ui:rereat value="#{catalogueBean.catalogue.children}" var="group"> 
         <li><h:outputText value="#{group.catalogueGroupName}" /></li> 
        </ui:repeat> 
    </ul> 
    

上述設置工作,但它感覺它是一個尷尬的。 所以,我想下面的開放,「最佳實踐」的問題提升到JSF社區:

  1. 什麼是建立一個目錄豆這樣的正確方法:
    • 一個@SessionScope的bean將被加載一次並在每個視圖上重新顯示,或者將在每個頁面顯示上訪問數據庫的bean。
  2. 有沒有辦法在的facelet視圖設置遞歸函數,或者我應該限制目錄嵌套級,比方說,2或3
  3. 我想顯示某種修改目錄,暴露更多羣組添加到已登錄的用戶,具體取決於他的角色(添加到數據庫表中的列),並在沒有用戶登錄時顯示基本目錄。此外,我想偶爾在目錄中插入一些新組,登錄,但一次重新顯示正確的數據:
    • 要過濾業務層中的組並將過濾後的CatalogueGroup暴露給bean,否則我將加載整個目錄並限制其c視圖中的hildren呈現= false;
    • 正在曝光整個目錄中的一個正確的方式去;
    • 是否有可能向服務器上的所有當前CatalogueBean活動刷新其屬性(CatalogueGroup)時添加新數據庫條目或實現此功能,我只需要使用@RequestScoped bean;
    • 如果使用請求作用域bean是唯一的選擇,那麼訪問數據庫是非常明智的選擇,以便頻繁獲取數據,而這些數據很少發生變化,或者存在更明智的做法;
    • 當用戶登錄(並註銷)時,已存在會話範圍目錄的實例,如何刷新它:我是否需要在操作/操作偵聽器中手動執行此操作,或者需要使會話無效或執行一些更合適的操作情況。

回答

1

非常有趣,但也許這麼開放的問題。

首先,範圍取決於您將提供給您的目錄的實用程序。如果你想將數據鏈接到特定的視圖或@SessionScoped,如果你的目標是實現類似購物籃的東西,我建議你通過@ViewScoped

對於遞歸函數,我認爲你應該避免純視圖(XHTML)層那種做法和使用圖書館像Primefaces或已內置組件爲你想要做什麼Richfaces。使用它們,你只需要在管理的支持bean內編程式地處理它們的邏輯結構。

最後,對於目錄限制,我建議你只加載你要從數據庫中使用的東西。這樣你就不會超載服務器數據庫服務器客戶端連接。您可以擁有一個管理當前登錄用戶會話的@SessionScoped bean,並根據該值可以向數據庫詢問某些值或其他值。

此外,如果您在會話期間對其進行了大量修改,可能需要關注您的目錄,或許@ViewScoped bean是一個更好的選擇,因爲每次請求視圖時它都會被實現。如果您使用@SessionScoped bean,那麼您必須手動添加其中的每個更改,以便在會話期間保持更新。

"load the whole catalogue and limit its children in views with rendered=false"

那是你沒有做,如果你做,我說的方式工作。如果您正在管理複雜的樹並向視圖中引入更多邏輯,那麼對每個樹節點進行條件評估可能會非常糟糕。當然,你應該儘可能避免這種情況。

即使你已經達成了一個解決方案,那是我的主要想法。

1

您可以使用緩存來存儲各種用戶角色的菜單。然後,當您在數據庫中插入新數據時(如果您從管理頁面中插入此數據),或者您可以將緩存設置爲在某段時間(每天一次,每幾小時等)後過期,則無效緩存當緩存過期時再讀取數據。