我正在开发中型Java应用程序,由于缺乏经验,我面临一个小问题。

我有一个自定义DAO,它从数据库中获取“Article”对象。我有Article类,DAO有一个名为getArticle(int id)的方法,该方法返回一个ArticleArticle有一个Category对象,我正在使用延迟加载。

因此,当我请求文章的类别(Article a = new Article(); a.getCategory();)时,Article类从DAO获取Category,然后将其返回。

我现在正在考虑对其进行缓存,因此当我多次请求文章的类别时,仅查询数据库一次。

我的问题是:我应该将该缓存放在哪里?我可以将其放在Article类(在DTO中)上,也可以将其放在DAO类上。

你怎么说?

最佳答案



正如其他人所提到的,听起来确实有点像重新发明轮子。但是无论如何,我们还是要考虑这两种情况,以便您更好地了解ORM的工作方式。

如果使用将类别存储在文章中,则同一类别将被不同的文章访问一次又一次。

getCategory() {
   if( category == null ) { category = <load from DAO> }
   return category;
}

如果将存储在DAO 中,则所有具有相同类别的文章都将使缓存受益,但是当类别更改时,您还需要注意更新缓存。
saveCategory( Category c ) {
     cache.put( c.id, c );
     <save in database>
}

这种方法的问题在于:(1)缓存可能会随着时间的推移而增长,并且(2)如果您没有超时机制或清除缓存的方法,则永远不会反射(reflect)数据库中的外部更新。

实际上,诸如Hibernate之类的ORM具有三个缓存级别:
  • 实体本身。当类别被延迟加载时,它将存储在商品实体中以供后续直接访问。
  • 一级缓存。这是当前 session /事务的缓存。同一实体不会被加载两次,而是会从缓存中获取。
  • 2级缓存。这是所有 session /事务的缓存。它对应于在DAO中缓存值的选项。由于我上面提到的原因,二级缓存有时会比较棘手。

  • 希望您能更好地看到每种类型的缓存的缺点/好处。有关更多信息,请参见流行的ORM文档。这些问题很常见并且有据可查。

    10-07 19:21
    查看更多