在JSP页面中缓存访问的值



在我的Javaweb应用程序中,我的整个数据库结构都被模型类覆盖。这真的很好,因为使用这些模型,我可以非常简单地直接在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>

不幸的是,我的数据库不支持联接,因此对于每一行,我都必须运行一个查询来从数据库中获取作者(这实际上非常快,因为作者是通过键存储在memcache中的)。假设我想在一个页面中使用两次循环(大菜单

小菜单我该如何避免这种情况?理想情况下,JSP"呈现器"应该将每个获取的值存储在临时缓存中(仅用于一个请求),下次使用该缓存值,而不是再次调用该方法。另一种方法是直接在模型对象中实现这个缓存,但我不知道如何在不重写一半代码的情况下高效地实现它。有什么想法吗?

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

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

您的模型对象不应该知道或关心它们是否被缓存。(仅仅因为你决定缓存或持久化它,它就相当于一本《作者》或《书》。)将缓存分开。

既然有这么多可用的东西,你为什么要写这样的东西?谷歌搜索类似EhCache或Terracotta的东西。

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

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

最新更新