I'm developing a medium Java app, and i'm facing a small problem due to my lack of experience.
I've a custom DAO, which gets "Article" objects from the Database. I've the Article
class, and the DAO has a method called getArticle(int id)
, this method returns an Article
. The Article
has a Category
o开发者_运维问答bject, and I'm using lazy loading.
So, when I request for an article's category (Article a = new Article(); a.getCategory();
) the Article
class gets the Category
from the DAO and then returns it.
I'm now thinking to cache it, so when I request multiple times to an article's category, the database is only queried one time.
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.
What do you say?
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.
As the others mentioned, it sounds indeed a bit like re-inventing the wheel. But let's consider both cases anyway, so that you will get better understanding of how ORM works.
If you store the category in the article, the same category will be loaded again and again if accessed by different articles.
getCategory() {
if( category == null ) { category = <load from DAO> }
return category;
}
If you store it in the DAO, then all articles with the same category will benefit the cache, but you need to take care to update the cache as well when the category is changed.
saveCategory( Category c ) {
cache.put( c.id, c );
<save in database>
}
Problem with this approach is that (1) the cache may grow large over time, and (2) that external update in the database will never be reflected if you don't have a timeout mechanism or a way to clear the cache.
Actually, ORM such as Hibernate have three levels of caching:
- The entity itself. When the category is lazy loaded, it's stored in the article entity for subsequent direct access.
- The first-level cache. This is the cache of the current session/transaction. The same entity won't be loaded twice but fetched from the cache.
- The 2nd-level cache. This is a cache across all sessions/transactions. It corresponds to the option of caching the value in the DAO. 2nd level cache is sometimes trickier because of the reasons I mentioned above.
Hope you see better the shortcomings/benefits of each type of cache. For more information, look in popular ORM documentation. Theses issues are common and well documented.
Have you considered using Hibernate?
The purpose of the DAO is to abstract away the persistence mechanism. Since 'where' the category comes from (DB, file on disk, network socket, Cache) is part of that persistence mechanism, the DAO should 'hide' it from the object consuming it.
Consider using Hibernate or even the more simpler form of it (JPA)
It depends on whether your Article
the only class to directly access the DAO or not.
Personally I would implement the caching in Article
for the simple fact that not everyone using the DAO will want caching. Also from a point of view of having one Class do one thing and one thing only, since you already have the lazy loading in Article
it wouldnt make sense to then move part of the way loading happens in the DAO
精彩评论