私のJava Web アプリケーションでは、データベース構造全体がModel クラスでカバーされています。これらのモデルを使用すると、データベースから何でもJSP ページに直接出力できるので、とても便利です。次の例を参照してください。
<c:if test="${fn:length(author.books) == 0}">The author has no books.</c:if>
<c:forEach items="${author.books}" var="book">
${book.name}
</c:forEach>
モデルには、データベースから関連する本を取得し、本を表すモデルのコレクションを返すAuthor
メソッドがあります。問題は、上記の例ではメソッドが実際に 2 回呼び出され、1 つの冗長なクエリが発生することです。getBooks()
を使用して値を保存できることはわかっています<c:set />
が、まず、それを頻繁に使用する必要があり (上記の例は私のアプリでは非常に一般的です)、次に、常に機能するとは限りません。例えば:
<c:forEach items="${books}" var="book">
${book.author.name}
</c:forEach>
残念ながら、私のデータベースは結合をサポートしていないため、行ごとにクエリを実行してデータベースから作成者を取得する必要があります (作成者はmemcache
キーで格納されているため、実際にはかなり高速です)。そして、このループを 1 つのページで2 回使用したいとしましょう(大きなメニューと小さなメニューなど)。したがって、各作成者はデータベース (または memcache) から 2 回フェッチされますが、これは実際には望ましくありません。
どうすればそれを回避できますか? 理想的には、JSP の「レンダラー」は取得した値をそれぞれ一時キャッシュに保存し(1 回の要求に対してのみ)、次回はメソッドを再度呼び出す代わりに、このキャッシュされた値を使用する必要があります。もう 1 つの方法は、このキャッシュをモデル オブジェクトに直接実装することですが、コードの半分を書き直さずに効率的に実装する方法がわかりません。何か案は?