我正在开发一个中型 Java 应用程序,由于缺乏经验,我遇到了一个小问题。
我有一个自定义 DAO,它从数据库中获取“文章”对象。我有 Article
类,DAO 有一个方法叫做 getArticle(int id)
,这个方法返回一个 Article
。 Article
有一个 Category
对象,我正在使用延迟加载。
因此,当我请求文章的类别时 (Article a = new Article(); a.getCategory();
) Article
类获取 来自 DAO 的类别
,然后返回它。
我现在想缓存它,所以当我多次请求一篇文章的类别时,数据库只被查询一次。
我的问题是:我应该把缓存放在哪里?我可以将它放在 Article
类中(在 DTO 中),也可以将它放在 DAO 类中。
你说呢?
最佳答案
My question is: where should I put that cache? I can put it on the Article class (in the DTO), or I can put it on the DAO class.
正如其他人所提到的,这听起来确实有点像重新发明轮子。但无论如何,让我们考虑这两种情况,以便您更好地理解 ORM 的工作原理。
如果您将类别存储在文章中,如果不同的文章访问相同的类别,将一次又一次地加载。
getCategory() {
if( category == null ) { category = <load from DAO> }
return category;
}
如果将其存储在 DAO 中,则所有具有相同类别的文章都将受益于缓存,但您需要注意在类别更改时更新缓存。 p>
saveCategory( Category c ) {
cache.put( c.id, c );
<save in database>
}
这种方法的问题在于 (1) 缓存可能会随着时间的推移而变大,并且 (2) 如果您没有超时机制或清除缓存的方法,数据库中的外部更新将永远不会反射(reflect)出来.
其实Hibernate等ORM有三级缓存:
- 实体本身。当类别被延迟加载时,它被存储在文章实体中以供后续直接访问。
- 一级缓存。这是当前 session /事务的缓存。同一个实体不会被加载两次,而是从缓存中获取。
- 二级缓存。这是所有 session /事务的缓存。它对应于在 DAO 中缓存值的选项。由于我上面提到的原因,二级缓存有时更棘手。
希望您能更好地了解每种缓存类型的缺点/优点。有关更多信息,请查看流行的 ORM 文档。这些问题很常见并且有据可查。
关于Java DAO 缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2815916/