简体   繁体   中英

Data transfer object in dao design pattern

I am bit confused about what data should a DTO contain. For example let's assume that we have two tables: User, and Orders. Orders table contains id_users, which is foreign key to user table.

Obviously I have two DAOs, MysqlUserDao and MysqlOrdersDao, with crud operations, and two transfer objects User, and Order, in which I store jdbc rowset.

If I want to get the list of users and for each user all his orders how should I do:

1) In my MysqlUserDao create a function: getUsersAndOrders(select users. ,orders. from users join orders) And my User DTO should have a OrderList property in where i put orders ?

2) In my MysqlUserDao i create a function getAllUsers(select * from users), and foreach user I use MysqlOrdersDao function getOrder(id_user);

And some clarifications:

1) For each table in database I need to create a DAO object? or just for complex ones? For example products and images, should be 2 dao or just one?

2) a DTO object should have only properties and setter getter, or it is possible to have other methods like convertEuroToUsd etc.

thanks

In your scenario #1 is the best option because #2 generates too much overhead.

1) In my MysqlUserDao create a function: getUsersAndOrders(select users.,orders. from users join orders) And my User DTO should have a OrderList property in where i put orders ?

Clarifications: 1: If your database has a good Design, then a DAO for each table is a good approach. There some cases where you can merge DAOs together (eg: inheritance).

2: Yes. It should be a plain bean (or POJO if you want). I suggest creating another layer where you can define your workflow. I've seem people calling this extra layer as model, sometimes DataManager, sometimes just Manager.

For instance: When creating a order you should insert a record in Order table and also insert a record in the Notification table (because end users will be notified via email every time a order is created)

class OrderManager {
   private OrderDAO oDao;
   private NotificationDao nDao;

   public saveOrder(OrderDTO o) {
      Long orderId = oDao.save(o);
      NotificationDTO n = new NotificationDTO();
      n.setType(NotificationType.ORDER_CREATED);
      n.setEntityId(orderId);
      nDao.save(n);
   }
}

UPDATE: In most cases we can say that:

  • "Managers" may handle many DAOs;
  • DAOs should not contain other DAOs and are tied to a DTO;
  • DTOs can contain other DTOs

There is an important idea of LAZY or EAGER load when it comes to handling collections. But this is another subject :D

Disclaimer: + The following assumes that these DTOs are used mainly for persistence, ie, for use with DAOs. + this approach is very oriented towards a relational database persistence + it is assumed a user can have placed orders, but that an order can have at most one user + also, that you want to query/process separatedly orders and users

I would have done the following:

  • a DTO for User (UserDTO + UserDAO)
  • a DTO for Orders (OrderDTO + OrderDAO)
  • a DTO to connect both (UserOrderDTO + UserOrderDAO)
  • I would not have references in the UserDTO to any OrderDTO
  • I may have a reference in the OrderDTO to the UserDTO as an attribute having a string id (being the string id the user id), but also I may not. I assume the later.
  • a Service Application to manage the different DAOs associated to the Order (OrderSA)

The resulting code would be as follows:

class OrderManagerServiceApplication {
   private OrderDAO oDao;
   private UserDao uDao;
   private UserOrderDao uoDao;

   public saveOrder(OrderDTO o, String userId) {
      // Save the order
      Long orderId = oDao.save(o);
      // Save the association to the user who ordered
      UserOrderDTO uodto=new UserOrderDTO(orderId,userId);          
      uoDao.save(uodto);
   }

   public List<OrderDTO> getOrdersForUser(String userId) { 
      // get the orders associated to the user  
      List<String> orderIds=uoDao.getAllForUser(userId);
      // retrieve the order DTOs
      ArrayList<OrderDTO> result=new ArrayList<OrderDTO>();
      for (String orderId:orderIds){
        result.add(oDAO.getOrder(orderId));
      }
      return result;
   }


   public UserDTO getUserForOrder(Stirng orderId) { 
      // get the user associated with the order
      String userId=uoao.getUserForOrder(orderId);
      // retrieve the user DTO
      return uDAO.getUser(userId);
   }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM