0

在我的Java Web 应用程序中,我的整个数据库结构都包含在Model classes中。这真的很简洁,因为使用这些模型,我可以非常简单地直接在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通过键存储的)。假设我想在一页中使用这个循环两次(大菜单小菜单或其他......)。因此,每个作者都从数据库(或 memcache)中获取了两次,这实际上是不希望的。

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

4

2 回答 2

0

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

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

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

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

于 2012-09-16T12:57:54.273 回答
0

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

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

于 2012-09-24T23:15:32.680 回答