dao设计模式中的数据传输对象
Posted
技术标签:
【中文标题】dao设计模式中的数据传输对象【英文标题】:Data transfer object in dao design pattern 【发布时间】:2013-07-11 13:11:12 【问题描述】:我对 DTO 应该包含哪些数据感到有些困惑。 例如,假设我们有两个表:User 和 Orders。 Orders 表包含 id_users,它是 user 表的外键。
显然,我有两个 DAO,mysqlUserDao 和 MysqlOrdersDao,具有 crud 操作,以及两个传输对象 User 和 Order,我在其中存储 jdbc 行集。
如果我想获取用户列表以及每个用户的所有订单,我应该怎么做:
1) 在我的MysqlUserDao中创建一个函数:getUsersAndOrders(select users.,orders. from users join orders) 我的用户 DTO 应该在我下订单的地方有一个 OrderList 属性?
2) 在我的 MysqlUserDao 中,我创建了一个函数 getAllUsers(select * from users), 而foreach用户我使用MysqlOrdersDao函数getOrder(id_user);
还有一些说明:
1) 我需要为数据库中的每个表创建一个 DAO 对象吗?还是只针对复杂的? 例如产品和图片,应该是 2 道还是只有 1 道?
2) DTO 对象应该只有属性和 setter getter,或者可以有其他方法,如 convertEuroToUsd 等。
谢谢
【问题讨论】:
【参考方案1】:在您的场景中,#1 是最佳选择,因为 #2 会产生太多开销。
1) 在我的 MysqlUserDao 中创建一个函数:getUsersAndOrders(select users.,orders. from users join orders) 我的 User DTO 应该在我下订单的地方有一个 OrderList 属性?
说明: 1:如果你的数据库有很好的设计,那么为每个表做一个DAO是一个很好的方法。在某些情况下,您可以将 DAO 合并在一起(例如:继承)。
2:是的。它应该是一个普通的 bean(如果需要,也可以是 POJO)。我建议创建另一个层,您可以在其中定义您的工作流程。我似乎有人称这个额外的层为模型,有时是 DataManager,有时只是 Manager。
例如:创建订单时,您应该在订单表中插入一条记录,同时在通知表中插入一条记录(因为每次创建订单时最终用户都会收到电子邮件通知)
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);
更新: 在大多数情况下,我们可以这样说:
“经理”可以处理许多 DAO; DAO 不应包含其他 DAO 并与 DTO 绑定; DTO 可以包含其他 DTO在处理集合时,LAZY 或 EAGER 加载有一个重要的想法。但这是另一个主题:D
【讨论】:
在您的示例中,我理解 OrderManager 的目的,但是如果我有一个简单的 DAO,只包含粗鲁操作,那么我认为 Manager 毫无意义。管理器中的插入函数如下所示: ` public insertOrder(OrderDto o ) oDao.insert(o)); ` .作为一项规则,传输对象应该包含所有其他处于连接关系的 DTO?像 orm 一样 @Catalin “作为一项规则,传输对象应该包含所有其他处于连接关系的 DTO?”。我想说这取决于,我们不能定义这么强的规则,有很多性能(如果你不加入,意味着你需要循环并稍后执行许多其他选择)和语义(用户是订单的内在组件吗? ) 需要考虑的问题。【参考方案2】:免责声明: + 以下假设这些 DTO 主要用于持久性,即与 DAO 一起使用。 + 这种方法非常面向关系数据库持久性 + 假设一个用户可以下订单,但一个订单最多只能有一个用户 + 还有,你想分别查询/处理订单和用户
我会做以下事情:
用户的 DTO (UserDTO + UserDAO) 订单的 DTO(OrderDTO + OrderDAO) 连接两者的 DTO (UserOrderDTO + UserOrderDAO) 我不会在 UserDTO 中引用任何 OrderDTO 我可能在 OrderDTO 中有对 UserDTO 的引用,作为具有字符串 id 的属性(作为用户 id 的字符串 id),但我也可能没有。我假设是后者。 用于管理与订单 (OrderSA) 关联的不同 DAO 的服务应用程序生成的代码如下:
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);
【讨论】:
以上是关于dao设计模式中的数据传输对象的主要内容,如果未能解决你的问题,请参考以下文章