Java DAO缓存

san*_*lto 5 java database caching

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

我有一个自定义DAO,它从数据库中获取"Article"对象.我是这个Article类,DAO有一个调用的方法getArticle(int id),这个方法返回一个Article.该Article有一个Category对象,我使用延迟加载.

因此,当我请求文章的category(Article a = new Article(); a.getCategory();)时,ArticleCategory从DAO 获取然后返回它.

我现在正在考虑缓存它,所以当我多次请求文章的类别时,只会查询一次数据库.

我的问题是:我应该把缓存放在哪里?我可以把它放在Article课堂上(在DTO中),或者我可以把它放在DAO课上.

你说什么?

Sua*_*ehi 8

你考虑过使用Hibernate吗?

  • 如果您提出了一个预先制定的解决方案,我认为最好也简要解释一下它是如何针对原始问题工作的,在这种情况下,是数据缓存。看我的回答。 (2认同)

ewe*_*nli 8

我的问题是:我应该把缓存放在哪里?我可以把它放在Article类(在DTO中),或者我可以把它放在DAO类上.

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

如果您在文章中存储类别,则如果由不同的文章访问,则会反复加载相同的类别.

getCategory() {
   if( category == null ) { category = <load from DAO> }
   return category;
}
Run Code Online (Sandbox Code Playgroud)

如果将它存储在DAO中,那么具有相同类别的所有文章都将使缓存受益,但是当更改类别时,您还需要注意更新缓存.

saveCategory( Category c ) {
     cache.put( c.id, c ); 
     <save in database>
}
Run Code Online (Sandbox Code Playgroud)

这种方法的问题在于:(1)缓存可能随着时间的推移而变大,以及(2)如果您没有超时机制或清除缓存的方法,则永远不会反映数据库中的外部更新.

实际上,像Hibernate这样的ORM有三个级别的缓存:

  1. 实体本身.当类别延迟加载时,它将存储在文章实体中以供后续直接访问.
  2. 第一级缓存.这是当前会话/事务的缓存.同一实体不会被加载两次,而是从缓存中获取.
  3. 二级缓存.这是所有会话/事务的缓存.它对应于在DAO中缓存值的选项.由于我上面提到的原因,二级缓存有时比较棘手.

希望您能更好地了解每种缓存的缺点/好处.有关更多信息,请查看流行的ORM文档.这些问题很常见且记录良好.