1.MVC与DDD数据相关

最本质的区别所在:依赖倒置领域模型的纯净性

1. MVC 做对比

在传统的 MVC 三层架构 中,流程通常是这样的:

  • Controller: 接待员,接收请求。

  • Service: 业务员,写业务逻辑。

  • Mapper/DAO: 仓库管理员,直接操作数据库。

路径: Controller Service Mapper(DAO) DB

MVC 的问题:

Service 层直接依赖 Mapper,意味着业务逻辑直接依赖了数据库表结构。如果数据库表改了,POJO(持久化对象)就得改,Service 里的 get/set 可能也得跟着改。业务逻辑被数据库“绑架”了。


2. DDD 架构下的“三方会谈”

在 DDD(你截图中的架构)中,为了让业务逻辑(Domain)不受数据库影响,引入了 Repository(仓储) 的概念,并把 Mapper/DAO 降级了。

我们来看你截图中的三个角色,它们的分工非常明确:

第一角色:IActivityRepository (接口)

  • 位置:domain 包(或其子包)里。

  • 身份: 业务部门提出的“需求合同”

  • 作用: 领域层(Domain)是大老板,它只规定:“我要根据 ID 查一个活动信息,我不管你去哪里查(MySQL、Redis、还是 Excel),反正你要给我返回一个标准的 领域实体(Entity)。”

  • 注意: 这里的方法返回值通常是 ActivityEntity(领域对象),而不是数据库对应的 ActivityPO(数据库表映射对象)。

第二角色:DAO (IRaffleActivityDao)

  • 位置:infrastructure (基础设置层) dao 包里。

  • 身份: 干脏活累活的“数据库操作员”

  • 作用: 它就是你熟悉的 Mapper。它只懂 SQL,只懂数据库表结构。它返回的是 PO (Persistent Object) 或者 DO (Data Object),也就是和数据库表 1:1 对应的对象。

第三角色:Repository Impl (ActivityRepository)

  • 位置:infrastructure repository 包里。

  • 身份: 适配器 / 转换器

  • 作用: 它是最关键的“胶水”。

    1. 实现了 Domain 层的 IActivityRepository 接口(履行合同)。

    2. 注入IRaffleActivityDao(使用工具)。

    3. 核心逻辑: 当 Domain 调用它时,它先指挥 DAO 去数据库查出 PO 数据,然后把 PO 转换(Convert)Entity,最后返回给 Domain。


3. 为什么要搞这么复杂?(核心价值)

你可能会问:直接用 DAO 不行吗?为什么要中间加一层 Repository?

原因有二:

  1. 依赖倒置(解耦):

    • 在 DDD 中,Domain 层(核心业务)不依赖 Infrastructure 层(数据库实现)

    • Domain 层定义接口(IActivityRepository),Infrastructure 层去实现它。这样,业务逻辑就不需要知道你用的是 MyBatis 还是 Hibernate,甚至换成 MongoDB,业务逻辑一行代码都不用改。

  2. 模型分离(PO vs Entity):

    • DAO 操作的是 PO:为了迎合数据库,可能有很多无关字段(如 is_deleted, create_time, update_time),或者是扁平化的结构。

    • Domain 需要的是 Entity:为了迎合业务,可能有丰富的行为方法(比如 activity.checkStatus()),或者复杂的聚合结构(一个对象里包含另一个对象 List)。

    • Repository 的实现类负责在两者之间做数据清洗和转换

4. 总结图解

结合你的截图,数据流向是这样的:

简单一句话总结

  • DAO:是数据库的代言人,说的是“SQL 语言”(表、行、列)。

  • IActivityRepository:是业务逻辑的代言人,说的是“业务语言”(活动、抽奖、用户)。

  • Repository 实现类:是翻译官,把 DAO 查出来的“数据”翻译成业务需要的“对象”。

2.DAO PO DO

  • DAO (Data Access Object)

    • 这是一个老牌的、通用的设计模式概念

    • 它的意思是“数据访问对象”。

    • 在早期的 Java (JDBC, Hibernate) 时代,我们习惯叫它 UserDao,实现类叫 UserDaoImpl

  • Mapper

    • 这是 MyBatis 框架 特有的叫法。

    • MyBatis 觉得“映射(Map)”这个词更准确——把 Java 方法映射成 SQL 语句。

    • 所以在 MyBatis 项目里,我们通常创建接口叫 UserMapper

缩写全称中文名它的身份它的位置
POPersistent Object持久化对象数据库的影子。它跟数据库表是 1:1 对应的。表里有 user_id,它就有 userId;表里有 is_deleted,它就有 isDeletedDAO层 / Mapper层
DOData Object数据对象通常等同于 PO。在阿里巴巴开发手册中,DO 就是数据库表对应的对象。但在某些别的架构里,它可能指“领域对象”,不过在你的项目中,它大概率就是 PO 的别名。DAO层 / Mapper层

PO ≈ DO。它们都是数据库表的 1:1 映射对象。