5

これはおそらく一種のアーキテクチャ上の質問ですが、それでも「ベストプラクティスソリューション」または受け入れられている標準が必要です。

製品のカタログ、メニューとメニュー項目のリスト、ブレッドクラムブロックのリストなど、サイトに表示する必要のあるある種の静的データについて話しています。このオプションは、標準の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. 次のようなカタログBeanを設定する適切な方法は何ですか。
    • @SessionScope一度ロードされ、すべてのビューに再表示されるBeanまたは
    • @RequestScopedすべてのページ表示でデータベースにアクセスするBean。
  2. フェイスレットビューで再帰関数を設定する方法はありますか、またはカタログのネストレベルをたとえば2または3に制限する必要があります。
  3. ある種の変更されたカタログを表示し、ユーザーの役割(データベーステーブルに追加された列)に応じて、ログインしたユーザーにより多くのグループを公開し、ユーザーがログインしていないときに基本的なカタログを表示したい。さらに、時々挿入したいカタログ内のいくつかの新しいグループは、ユーザーに再ログインを強制しませんが、適切なデータを一度に再表示します。
    • ビジネスレイヤーでグループをフィルタリングし、フィルタリングされたCatalogueGroupをBeanに公開するか、カタログ全体をロードして、rendered=falseのビューでその子を制限します。
    • セッション中のカタログ全体の公開は適切な方法ですか。
    • サーバー上でアクティブな現在のすべてのCatalogueBeanに新しいデータベースエントリを追加する際に変更イベントを送信して、プロパティ(CatalogueGroup)を強制的に更新したり、この機能を実現したりすることはできますか?@RequestScopedBeanのみを使用する必要があります。
    • リクエストスコープのBeanを使用することが唯一の代替手段である場合、データベースにアクセスしてデータを取得することが賢明であり、ほとんど変更されないか、よりスマートな方法があります。
    • ユーザーがログイン(およびログアウト)すると、セッションスコープのカタログのインスタンスがすでに存在します。それを更新する方法:アクション/アクションリスナーで手動で実行する必要がありますか、セッションを無効にするか、状況により適切なことを実行する必要がありますか? 。
4

2 に答える 2

1

非常に興味深いですが、多分とてもオープンな質問です。

まず、スコープは、カタログに提供するユーティリティによって異なります。@ViewScopedデータを特定のビューにリンクする@SessionScoped場合、または買い物かごのようなものを実装することを目的とする場合は、通過することをお勧めします。

再帰関数については、純粋なビュー(xhtml)レイヤーでのそのような練習を避け、実行したいことのための組み込みコンポーネントを備えたPrimefacesRichfacesのようなライブラリを使用する必要があると思います。それらを使用すると、管理対象のバッキングBean内でプログラムによって論理構造を処理するだけで済みます。

最後に、カタログの制限については、使用するものだけをデータベースからロードすることをお勧めします。このようにして、サーバーデータベース接続もサーバークライアント接続も過負荷になりません。現在ログに記録されているユーザーのセッションを管理する@SessionScopedBeanを作成し、それに応じてデータベースにいくつかの値またはその他の値を要求できます。

また、カタログに注意する必要があります。セッション中にカタログに多くの変更を加える場合は、@ViewScopedビューが要求されるたびに再ロードされるため、Beanの方が適している可能性があります。そのためにBeanを使用する場合@SessionScopedは、セッション中に更新された状態を維持するために、各変更を手動で追加する必要があります。

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

私の言う通りにやれば、それはあなたがする必要のない仕事です。複雑なツリーを管理していて、ビューにより多くのロジックを導入している場合、各ツリーノードを条件付きで評価するのは大変な作業になる可能性があります。間違いなく、できる限りそれを避けるべきです。

あなたがすでに解決策に到達しているとしても、それが私の主な考えです。

于 2013-01-22T09:15:04.920 に答える
1

キャッシュを使用して、さまざまなユーザーロールのメニューを保存できます。次に、データベースに新しいデータを挿入するときにキャッシュを無効にするか(管理ページから挿入する場合)、一定期間(1日1回、数時間ごとなど)後にキャッシュを期限切れにするように設定できます。キャッシュの有効期限が切れたら、データを再度読み取ります。

于 2013-01-22T09:58:56.207 に答える