Java 项目包命名中常见 mapper 或 dao,它们有何区别?该选哪个?

引言

在 Java 企业级项目中,mapper 和 dao 都代表数据访问层(持久层),但它们的起源、设计理念和框架绑定有所不同。

简单来说:DAO 是一种通用的设计模式,而 Mapper 是 MyBatis 框架特有的实现方式。

详细对比与分析

维度 DAO (Data Access Object) Mapper (映射器)
本质​ 一种通用设计模式(GOF/JEE模式)。 MyBatis 框架特有的概念(接口+XML映射)。
起源​ 早在 EJB 2.x 时代就存在的 Java EE 标准模式。 MyBatis(原 iBatis)框架引入,用于绑定 SQL。
核心思想​ 封装对数据源(不仅是数据库,也可以是文件、LDAP等)的访问逻辑,为业务层提供抽象接口。 将 Java 接口方法与 SQL 语句(XML/注解)进行映射,让开发者只关心接口,不写实现类。
典型包名​ dao 或 repository mapper
典型类名​ UserDAO / UserDao UserMapper
框架依赖​ 无依赖,任何框架(JDBC、Hibernate、MyBatis)都可以实现 DAO 模式。 强依赖 MyBatis,离开 MyBatis 环境毫无意义。
实现方式​ 早期需要自己写实现类(如 UserDAOImpl 写 JDBC 代码),后来 Spring 可以用模板类或代理。 完全不需要写实现类,MyBatis 通过动态代理在运行时自动生成实现。

详细场景说明

DAO (Data Access Object)

DAO 模式的核心目的是解耦。业务层(Service)不需要知道数据是从 MySQL、Oracle 还是 MongoDB 取出来的,它只依赖 UserDAO 接口。

  • 在 JPA/Hibernate 项目中:通常会有一个 UserDAO 接口,里面可能继承 JpaRepository,或者自己写 HQL。
  • 在早期的 JDBC/MyBatis 项目中:你会看到 UserDAO 接口和 UserDAOImpl 实现类,实现类里写满了 SqlSession 调用或 JDBC 代码。
Mapper (映射器)

Mapper 是 MyBatis 的“杀手锏”。你只需要写一个接口(如 UserMapper.java)和一个 XML 文件(如 UserMapper.xml),MyBatis 会在运行时动态生成这个接口的实现类,并帮你执行 XML 里绑定的 SQL。

  • 特点:接口里的方法名、参数、返回值,与 XML 里的 id、parameterType、resultType 一一对应。
  • 本质:Mapper 其实就是 MyBatis 对你项目里“数据访问对象”的具体称呼。

为什么很多 MyBatis 项目里,包名用 dao 还是 mapper 都有?

这是一个历史习惯问题:

1. 包名用 dao:

开发者受传统 Java EE 教育影响,认为“这一层就是 DAO 层”,所以包名叫 dao。

里面的接口其实还是叫 UserMapper(因为要加 @Mapper 注解),或者叫 UserDAO 但本质是 Mapper。

现状:很多老项目或习惯传统的团队喜欢这么干。

2. 包名用 mapper:

开发者认为“既然技术栈是 MyBatis,那就明确告诉别人这是 Mapper”,见名知意。

里面的接口就叫 UserMapper。

现状:目前使用 MyBatis / MyBatis-Plus 的新项目,绝大多数推荐使用 mapper 作为包名,因为这是框架的原生术语,不会与 JPA 的 Repository 或传统 DAO 模式混淆。

选型建议(该用哪个?)

Java 项目技术栈如果是 MyBatis,坚持使用 mapper 包名和 XxxMapper 接口命名,是当前最主流、最清晰的企业级规范。

总结

DAO 是“做什么”(数据访问),Mapper 是“怎么做”(MyBatis 的 SQL 映射实现)。

posted @ 2026-09-04 08:53  Binge-和时间做朋友  阅读(28)  评论(0)    收藏  举报