DAO和DTO的区别

本文深入解析数据传输对象(DTO)和数据访问对象(DAO)的概念,探讨二者在软件架构中的角色与作用。DTO用于表现层与应用层间的数据传递,而DAO则负责数据库访问,隐藏底层细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DTO:数据传输对象(Data Transfer Object),是一种设计模式之间传输数据的软件应用系统。数据传输目标往往是数据访问对象从数据库中检索对象。与POPJ对应一个数据库实体不同,DTO并不对应一个实体,可能仅存储实体的部分属性或加入符合传输需求的其他的属性。

DAO:数据访问对象(Data Access Object)。提供访问数据库的接口,或者持久化机制,而不暴露数据库的内部详细信息。DAO提供从程序调用到持久层的匹配。

表现层和应用层之间是通过数据传输对象(DTO)进行交互的,数据传输对象是没有行为的POCO对象,它的目的只是为了对领域对象进行数据封装,实现层与层之间的数据传递。为何不能直接将领域对象用于数据传递?因为领域对象更注重领域,而DTO更注重数据。不仅如此,由于“富领域模型”的特点,这样做会直接将领域对象的行为暴露给表现层。

需要了解的是,数据传输对象DTO本身并不是业务对象。数据传输对象的根据UI的需求进行设计的,而不是根据领域对象进行设计的。比如,Customer领域对象可能会包含一些诸如FirstName,LastName,Email,Address等信息。但如果UI上不打算显示Address的信息,那么CustomerDao中也无需包含这个Address的数据。

简单来说Model面向业务,我们是通过业务来定义Model的。而DTO是面向界面UI,是通过UI的需求来定义的。通过DTO我们实现了表现层与Model之间的解耦,表现层不引用Model,如果开发过程中我们的模型改变了,而界面没变,我们就只需要修改Model而不需要去改表现层中的东西。

### DAO模式与DTO模式的概念 #### 数据访问对象 (DAO, Data Access Object) DAO是一种设计模式,旨在通过封装底层数据库操作逻辑来简化数据访问层的设计。它提供了统一的接口供上层业务调用,从而屏蔽了具体的数据存储细节[^1]。这种方式使得应用程序可以更加灵活地应对不同的数据源变化。 #### 数据传输对象 (DTO, Data Transfer Object) 相比之下,DTO主要用于解决分布式系统中的性能瓶颈问题。它的核心目的是减少网络通信次数以及降低带宽消耗。通常情况下,在客户端服务端交互过程中,会创建一个专门的对象用来承载所需传递的信息集合——这就是所谓的“胖对象”,即包含了多个属性值的一个实体类实例[^2]。 --- ### 主要区别 | 特性 | DAO | DTO | |--------------------|-----------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------| | **主要功能** | 提供对持久化机制的操作接口 | 负责在不同组件之间交换数据 | | **关注点** | 如何高效、安全地完成增删改查等基础CRUD操作 | 怎样最小化远程调用开销并保持清晰简洁的数据结构 | | **适用范围** | 局限于同一进程内的数据存取控制 | 广泛应用于跨服务边界的场景 | 从上述表格可以看出两者虽然都涉及到软件架构层面的重要组成部分,但是它们各自侧重点完全不同:前者更偏向于是面向资源管理;后者则是为了满足远距离通讯需求所诞生的一种解决方案. 另外值得注意的是,在实际开发当中我们往往会发现这两种技术并非孤立存在而是相辅相成的关系。例如当采用微服务体系构建大型项目时,可能就需要先利用DAO去处理本地事务然后再借助DTO把结果返回给外部请求方。 --- ### 应用场景分析 对于需要频繁进行复杂查询或者大量更新的企业级应用来说,单独依靠传统的SQL语句显然不够理想,此时引入DAO能够极大地提高可维护性扩展能力。与此同时如果考虑到系统的整体吞吐量,则应该考虑适当增加一些轻量化版本的结果集表示形式也就是我们的DTOs,这样既可以保留原有逻辑又不会因为过多冗余字段拖累效率。 以下是两种典型的应用案例: - 当某个电商平台想要展示商品列表页面的时候,后台可以通过DAO加载必要的产品详情信息,并组装成为适合前端渲染所需的紧凑型JSON格式响应体(即DTO),最终发送出去。 - 另外在一个跨国团队协作平台里头,为了避免每次同步状态都要重新拉取整个用户档案资料库的内容,我们可以预先定义好只包含关键变更项的小规模载体作为中间媒介来进行周期性的增量刷新动作。 ```java // 示例代码片段展示了如何结合使用DAODTO public class ProductDao { public List<Product> getProducts() { ... } // 使用DAO获取原始数据 } @Data @AllArgsConstructor @NoArgsConstructor public class ProductDto implements Serializable{ private String name; private double price; } @Service public class ProductService { @Autowired private ProductDao productDao; public List<ProductDto> fetchProductDtos(){ List<Product> products = this.productDao.getProducts(); return products.stream() .map(p -> new ProductDto(p.getName(), p.getPrice())) .collect(Collectors.toList()); } } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值