ORM and DAO - design question
I'm currently working on the project where this discussion came and I wanted to ask others what do they think about this.
The DAO pattern is (according to wikipedia): "In computer software, a data access object (DAO) is an object that provides an abstract interface to some type of database or persistence mechanism, providing some specific operations without exposing details of the database.".
But, using ORM this is clearly an ORM (eg. Hibernate) job. It exactly provides an abstract interface to some (almost any) type of database.
Reviewing few last projects let's look on the DAO layer. First step is always generic hibernate dao with save(), findById(), findAll() methods. This is for me just proxying hibernate session methods.
A step further I see such interfaces like proposed here: Generic DAO pattern in Hibernate, what completely tightly bounds the DAO to hibernate way of doing persistence (merge, criteria query). This DAO wont be usable with other persistence mechanism than Hibernate.
So the final though is a question: for such common DAO design what new brings DAO pattern? If I want to switch database engine, I'm switching it on hibernate level. So, is this really any benefits currently from using DAO patterns in ORM applications?
Let's collect some experience:
开发者_JAVA技巧- How many times have you seen the DAO class hierarchy tightly bound to Hibernate (or other ORM) and what do you think about benefits from that?
- In how many projects do you changed the persistence mechanism in the way that you got benefits from DAO layer (ie. you needed to implement other DAO layer because your job cannot be done on ORM level by switching db dialect)?
- In how many projects you just developed large DAO structure (interface+class for each domain object) and never used this really (ie. you never changed implementation of base DAO hierarchy)?
- What do you think, then, about applications without DAO layer, just using the abstraction provided by ORM sessions?
Please share with experience.
IMHO, the DAO pattern, when using an ORM, is not really about the ability to switch the database engine. It's about
- separating the responsibilities: business logic goes to the service layer, persistence goes to the DAO layer
- being able to test the service layer by mocking the DAO layer
- being able to test the persistence logic, because it's not buried inside the business logic
I usually prefer not to have a DAO per domain object, but rather a DAO per set of functional use-cases. Indeed, I've found that most of the queries, in a sufficiently complex application, are not linked to a specific domain object, but rather to a use-case or a set of use-cases. But YMMV, and combining both approaches is sometimes useful.
So, to answer your specific questions:
- nearly always. Using a DAO using Hibernate or JPA is not the same as using a DAO using plain JDBC, most of the time
- never. Usually, the choice of the database is done long before the project starts, and never changes.
- I tend to only develop a DAO when I need it, and not because a domain object exists. But having a "generic DAO" base class is sometimes handy
- I think they're harder to test, are often not well-structured, and end up reimplementing the same queries/loadings over and over again because those are not isolated in a reusable DAO
精彩评论