Daulet Nurgali
Daulet Nurgali

Reputation: 167

Can DAO be used for multiple tables ?

I am in the process of development of small app in javaSE just to make my skills better. So I have business service (BS further) where some methods are like registerUser(User user), addAmount(Long accountId). BS uses dao. Lets assume BS is called from WS or other interface element. I have following DAOs:

public interface UserDao {

    User getUserByUsername(String username);

    void saveUser(User user);
}

public interface AccountDao {

    void saveAccount(Account account);

    Account getAccountByUserId(Long userId);
}

My BS looks like

public class FastAccountServiceImpl implements FastAccountService{

private UserDao userDao;
private AccountDao accountDao;

public void registerUser(User user, Account account) throws Exception {
    if (user.getUsername() == null || user.getUsername().isEmpty()) {
        throw new Exception("all params are mandatory");
    }
    if (userDao.getUserByUsername(user.getUsername()) != null) {
        throw new Exception("This user exists");
    }
    userDao.saveUser(user);
    accountDao.saveAccount(account);
}

public void withdrawAmount(Double amount, Long userId) throws Exception {
    if (amount == null || userId == null) {
        throw new Exception("amount and userId are mandatory");
    }
    Account account = accountDao.getAccountByUserId(userId);
    if (account.getAmount() == null || account.getAmount().compareTo(amount) < 1) {
        throw new Exception("Insufficient amount in account");
    }......

}}

So my first question is where should I check params for null etc ? In BS ? Second question is why should we have separate dao for every table ? Can I create just one dao for all tables. So in BS there only one dao will be. This dao is represented below:

public interface MagicDao {

User getUserByUsername(String username);

void saveUser(User user);

void saveAccount(Account account);

Account getAccountByUserId(Long userId);

}

Upvotes: 2

Views: 6549

Answers (1)

vikingsteve
vikingsteve

Reputation: 40438

Yes checking for nulls in the business service is better than checking for them in the Dao, since this is a layered architecture and checking in the BS happens earlier.

As for why "one Dao per table" - well, Dao´s have a habit of becoming much more complex over time, so if you have 2 operations on "Account" table right now, in future there could well be 10 or 20 operations, so a cohesive 1-to-1 approach is more manageable and also more easily testable.

So I would certainly avoid MagicDao. The job of operating across tables is the role of the service (or some other pattern, like a Facade) - not the Dao, at least per common convention.

Besides, modern dependency injection frameworks make it simple to declare and use all the Daos you need in the service. Theres no problem with having 5 or more Daos in a business service (one per table) - I see that quite commonly in code that I work with.

By the way you could use IllegalArgumentException in the places where you are throwing Exception - its more explicit and its also a RuntimeException (so you don't need to declare it with throws)

Upvotes: 9

Related Questions