DAO与Mapper:数据访问层的两种实现范式

引言:困惑的起源

在Java持久层开发中,我们经常会同时遇到DAO和Mapper这两个概念。许多开发者会产生这样的疑问:它们是不是同一种东西的不同叫法?为什么MyBatis用Mapper而不用DAO?本文将系统解析二者的关系,帮助开发者建立清晰的认识。

一、核心概念解析

1. DAO:经典设计模式

DAO(Data Access Object)是一种设计模式,最早出现在J2EE核心模式中。它的核心价值在于:

  • 抽象接口:定义数据访问的标准方法
  • 实现分离:业务层不依赖具体数据库操作
  • 统一契约:为不同数据源提供一致访问方式
// 典型DAO接口
public interface UserDao {
	User findById(Long id);
	List<User> findAll();
	void save(User user);
}

2. Mapper:MyBatis的实现方式

Mapper是MyBatis框架对DAO模式的具体实现,其特点包括:

  • 接口绑定:Java接口直接映射SQL语句
  • 动态代理:运行时自动生成实现类
  • SQL解耦:SQL保存在XML或注解中
// MyBatis Mapper示例
public interface UserMapper {
	@Select("SELECT * FROM users WHERE id = #{id}")
	User findById(Long id);
}

二、二者关系图解

[数据访问层抽象]
│
├── DAO(设计模式)
│	├── JDBC实现(传统DAO)
│	├── Hibernate实现
│	└── JPA实现
│
└── Mapper(MyBatis对DAO的实现)
	├── XML配置方式
	└── 注解配置方式

三、本质区别与联系

维度DAOMapper
抽象级别设计模式框架实现
实现方式需编写接口和实现类只需接口,自动生成实现
SQL管理通常嵌入Java代码分离在XML/注解中
技术绑定通用,跨框架特定于MyBatis
灵活性实现方式完全可控受限于MyBatis机制

关键结论:Mapper是DAO模式在MyBatis框架中的特定实现形式,就像"汽车是交通工具的一种具体实现"。

四、演进历程

  1. 传统DAO时代(2000年代初)
  • 每个DAO接口都需要对应的实现类
  • 大量重复的JDBC样板代码
  • 典型实现:Spring的JdbcTemplate
  1. ORM框架兴起(2005年后)
  • Hibernate等框架简化数据访问
  • 仍保持DAO模式的思想
  • 实现类由框架部分简化
  1. MyBatis的Mapper革命(2010年后)
  • 完全消除实现类
  • SQL与Java代码彻底解耦
  • 动态代理自动生成实现
  1. 现代演进(Spring Data时代)
public interface UserRepository extends JpaRepository<User, Long> {
// 结合了DAO和Mapper的优点
}

五、实践建议

何时使用传统DAO?

  1. 需要支持多种数据库
  2. 使用非MyBatis的持久层框架
  3. 需要精细控制数据访问逻辑
  4. 项目已有成熟的DAO基础设施

何时选择Mapper?

  1. 使用MyBatis技术栈
  2. 需要快速开发迭代
  3. 强调SQL的可维护性
  4. 希望减少样板代码

代码风格对比

传统DAO实现

public class UserDaoImpl implements UserDao {
	private final JdbcTemplate jdbcTemplate;
	
	@Override
	public User findById(Long id) {
		String sql = "SELECT * FROM users WHERE id = ?";
		return jdbcTemplate.queryForObject(sql, this::mapRow, id);
	}
	
	private User mapRow(ResultSet rs, int rowNum) throws SQLException {
		User user = new User();
		user.setId(rs.getLong("id"));
		// 其他字段映射...
		return user;
	}
}

MyBatis Mapper实现

<!-- UserMapper.xml -->
<mapper namespace="com.example.UserMapper">
	<select id="findById" resultType="User">
		SELECT * FROM users WHERE id = #{id}
	</select>
</mapper>

六、常见误区澄清

  1. 误区:“Mapper是DAO的替代品”
  • 正解:Mapper是DAO的一种实现方式
  1. 误区:“用了MyBatis就不需要DAO模式”
  • 正解:MyBatis的Mapper本身就是DAO模式的体现
  1. 误区:“DAO必须要有实现类”
  • 正解:实现方式取决于框架,MyBatis通过动态代理省去实现类

结语:理解本质,灵活运用

理解DAO与Mapper的关系,关键在于区分设计模式具体实现的层次差异。DAO作为经典模式,定义了数据访问层的基本规范;Mapper作为MyBatis的实现方式,提供了更便捷的开发体验。

在实际项目中,开发者应该:

  1. 在架构层面遵循DAO模式的思想
  2. 在实现层面根据技术栈选择合适方式
  3. 保持接口设计的业务语义明确
  4. 关注SQL的可维护性和性能优化

正如软件工程中许多抽象与实现的关系一样,掌握这种分层思考方式,将帮助我们在复杂的技术生态中保持清晰的设计思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值