缓存JSP页面中访问的值

时间:2012-09-16 12:53:04

标签: java jsp caching

在我的 Java Web应用程序中,我的整个数据库结构都包含在模型类中。它非常简洁,因为使用这些模型我可以直接在 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有一个方法getBooks(),它从数据库中提取相关图书并返回代表图书的集合模型。问题是在上面的例子中,该方法实际上被调用了两次,导致一个冗余查询。

我知道我可以使用<c:set />存储该值,但首先,我会使用很多(上面的示例在我的应用中很常见),其次,它不会永远不会工作。例如:

<c:forEach items="${books}" var="book">
${book.author.name}
</c:forEach>

遗憾的是,我的数据库不支持联接,因此对于每一行,我必须运行查询以从数据库中获取作者(实际上它非常快,因为作者存储在{{1通过键)。我们假设我想在一个页面中使用此循环两次大菜单小菜单或其他......)。因此,每个作者都从数据库(或内存缓存)中获取两次,这实际上是不可取的。

我该如何避免?理想情况下,JSP“渲染器”应该每个获取值存储在临时缓存中(仅针对一个请求),并且下次使用此缓存值而不是再次调用该方法。另一种方法是直接在模型对象中实现此缓存,但我不知道如何有效地执行此操作而不重写我的一半代码。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

JSP不应该做任何这样的事情。它们仅供展示。

通常的习惯用法称为Web的Model-2 MVC:servlet充当前端控制器并将JSP请求路由到后端服务。它应该封送JSP需要显示的值。它是执行所有逻辑的后端。这包括数据来自何处:缓存,数据库或实时计算。

您的模型对象不应该知道或关心它们是否被缓存。 (它不仅仅是作者或书籍,因为您决定缓存或持久化它。)保持缓存分离。

为什么在有这么多可用的时候你会想写这样的东西?谷歌的东西,如EhCache或Terracotta。

答案 1 :(得分:0)

最大的问题是第二个描述的例子 - 我想避免从数据存储区(或内存缓存区)重复获取相同的实体。幸运的是,所有实体都是在完全分离的层中获取的。我更新了这个层,以便现在每个获取的实体都通过其键存储在HashMap中。此HashMap用作简单缓存 - 当一个实体需要多次时,仅在第一种情况下使用该缓存值后才会获取它。请求完成后,将清除此HashMap。

这更像是一种解决方法,而不是真正的解决方案,我仍然对其他想法感兴趣。