Java DAO缓存

Java DAO缓存,java,database,caching,Java,Database,Caching,我正在开发一个中型Java应用程序,由于缺乏经验,我面临一个小问题 我有一个自定义DAO,它从数据库中获取“Article”对象。我有Article类,DAO有一个名为getArticle(intid)的方法,这个方法返回一个Article。文章有一个类别对象,我正在使用延迟加载 因此,当我请求一篇文章的类别(article a=newarticle();a.getCategory();)时,article类从DAO获取类别,然后返回它 我现在想缓存它,所以当我多次请求一篇文章的类别时,数据库只

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

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

因此,当我请求一篇文章的类别(
article a=newarticle();a.getCategory();
)时,
article
类从DAO获取
类别,然后返回它

我现在想缓存它,所以当我多次请求一篇文章的类别时,数据库只被查询一次

我的问题是:我应该把缓存放在哪里?我可以把它放在
文章
类中(在DTO中),也可以放在DAO类中


你说呢?

你考虑过使用吗?

DAO的目的是抽象出持久性机制。由于类别的“位置”(DB、磁盘上的文件、网络套接字、缓存)是持久性机制的一部分,DAO应该对使用它的对象“隐藏”它。

这取决于您的
文章是否是直接访问DAO的唯一类


就我个人而言,我将在
文章
中实现缓存,因为并非所有使用DAO的人都需要缓存。另外,从让一个类做一件事和只做一件事的角度来看,由于您在
文章中已经有了延迟加载,因此在DAO中移动加载方式的一部分是没有意义的

考虑使用Hibernate或更简单的形式(JPA)

我的问题是:我应该把它放在哪里 那个储藏室?我可以把它放在桌子上 文章类(在DTO中),或者我可以 把它放在DAO类上

正如其他人提到的,这听起来确实有点像重新发明轮子。但是无论如何,让我们考虑这两种情况,这样你就可以更好地理解ORM是如何工作的。 如果您将该类别存储在文章中,如果不同的文章访问同一类别,则会反复加载该类别

getCategory() {
   if( category == null ) { category = <load from DAO> }
   return category;
}
getCategory(){
如果(category==null){category=}
退货类别;
}
如果将其存储在DAO中,则具有相同类别的所有文章都将受益于缓存,但在更改类别时也需要注意更新缓存

saveCategory( Category c ) {
     cache.put( c.id, c ); 
     <save in database>
}
saveCategory(c类){
cache.put(c.id,c);
}
这种方法的问题在于:(1)缓存可能会随着时间的推移而变大,(2)如果没有超时机制或清除缓存的方法,数据库中的外部更新将永远不会被反映出来

实际上,ORM(如Hibernate)有三个级别的缓存:

  • 实体本身。当类别延迟加载时,它将存储在项目实体中,以供后续直接访问
  • 一级缓存。这是当前会话/事务的缓存。同一实体不会加载两次,而是从缓存中提取
  • 二级缓存。这是跨所有会话/事务的缓存。它对应于在DAO中缓存值的选项。由于我上面提到的原因,二级缓存有时比较棘手
    希望您能更好地了解每种类型缓存的缺点/优点。有关更多信息,请查看流行的ORM文档。这些问题是常见的,并且有很好的记录

    没错,没有必要重新发明轮子。自己实现某种缓存可能是一个有趣的练习,但是如果您只是想让应用程序工作,那么就使用Hibernate。它有自动为您处理缓存的功能,您在使用行业标准ORM框架时将获得一些宝贵的经验。如果您提出一个预先制定的解决方案,我认为最好也简单地解释一下它是如何工作的w.r.t最初的问题,在本例中,数据缓存。看我的答案。谢谢,这是一个真正的建筑师的答案。我知道Hibernate,实际上我使用JPA,但我用过Hibernate。我试着自己做,就像一个霍比。我想我将使用实体和二级缓存,以及一些观察者和超时。再次感谢兄弟!