views:

627

answers:

3

i thinking of doing this architecture

genericdao +interface ---> servicelayer+interface---> view layer

my dao will only have generic methods, my service layers will have real logic for instance

service layer method

string executeThis= "select c from com.abc.test.User where username =:username";
Map tempMap = new HashMap();
tempMap.put("username","abc");
return callDaoInferface.executeGenericList(executeThis,tempMap);   //get from DI

Do you this this is good architecture

my question is whether suitable to move the "select.." statement from dao into service layer

+1  A: 

Not really, no. What is the 'tempMap' doing? It seems a little weird.

Noon Silk
tempMap is Map that will be pass to Query.setParameter(..,..)
cometta
Yes ... :) Well, what I'm getting at is that it isn't typed as an Entity, or a collection of entities. That's my preferred way of doing it (and, infact, I just use an OR/Mapper: LLBLGen [for .NET]). Java, I'm sure, has well-known OR/Mappers that would do this for you. I suggest you use them.
Noon Silk
is that something like codegen ? appfuse? spring roo?
cometta
None of the above. ORM for Java would be Hibernate, TopLink, etc.
duffymo
+2  A: 

Your use of interfaces is pretty much the way Spring does it, whether or not you use generic DAOs. It includes the web tier as part of the view.

I'm not crazy about your service code. The whole point of the persistence interface is to abstract SQL away from clients, yet you've let SELECT leak into your service layer. Wrong, in my opinion.

There's little or nothing object-oriented about the way you're doing things.

I'm assuming that "generic dao" means something like this.

I've done it with Spring and Hibernate. The generic DAO interface looked like this:

package persistence;

import java.io.Serializable;
import java.util.List;

public interface GenericDao<T, K extends Serializable>
{
    List<T> find();
    T find(K id);
    List<T> find(T example);

    K save(T instance);
    void update(T instance);
    void delete(T instance);
}

So if I have User and Book model objects, I might have two DAOs like this:

GenericDao<User, Long> userDao = new GenericDaoImpl<User, Long>(User.class);
GenericDao<Book, String> bookDao = new GenericDaoImpl<Book, String>(Book.class);

The GenericDaoImpl is either an exercise for you or will have to wait until I can post the source code.

duffymo
my question is whether this is good architecture. i understand spring can do it. my question is whether suitable to move the "select.." statement from dao into service layer
cometta
Yes, your interfaces are correct - that's the Spring architectural idiom. Your implementation is wrong. SELECT statements belong in persistence.
duffymo
yes. i very agreed with you that why i ask to confirm. if i have a method like public List<T> search(String sqlStatement, Map keyValue){} in dao, i will have to create another method in dao with "select.. statement" to call it. my service layer will call the latter method. what do u think?
cometta
No, wrong. I don't think your way abstracts anything, so I think it's wrong. You should abandon this idea. There's no encapsulation the way you want to do it.
duffymo
The service layer should have no knowledge of how the DAO fetches its data. This means that the DAO interface should not have any method parameters for things like "sqlStatement". What if you ever have a DAO that fetches data from a message queue, XML file, flat file, etc?
matt b
+2  A: 

Your architecture is just a little off.

You want a dao interface to abstract succinct db interactions, or in other words, you could implement the data access contract with various implementations, such as JPA, Hibernate, Oracle, JDBC, etc. Your queries should reside with the implementation, and you should look into named queries, which I know exists in Hibernate and JPA. Queries could be different based upon the implementation, such as db specific nuances (like MySQL's 'limit') or HQL (Hibernate Query Language) vs. SQL.

In my opinion, a service layer in most instances (like this one) is simply overhead. You would want a service for something like user authorization, where your service layer might perform some business logic to properly construct the lookup. For example, you might need to encrypt/decrypt a password, or verify that a username doesn't already exists, minimum password requirement satisfaction, etc.

Duffy's generic DAO example is pretty much the standard and I would suggest implementing a variation of that...e.g. UserDaoHibernateImpl extends GenericDao<User, Long>

Droo
mean,if i have book and user ,car entities, i would have to BookDaoHibernateImpl extends GenericDao<Book, Long>; UserDaoHibernateImpl extends GenericDao<User, Long>;CarDaoHibernateImpl extends GenericDao<User, Long>;
cometta
No. You'd have GenericDao. If I were doing this in Spring, I'd have to create beans for each model object, but I would still only have one GenericDaoImpl. No "extends" in sight.
duffymo