温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java DAO 数据访问对象如何设计

发布时间:2026-07-24 19:27:38 来源:亿速云 阅读:101 作者:小樊 栏目:编程语言

在 Java 中,DAO(Data Access Object,数据访问对象)是一种常见的设计模式,用于把业务逻辑与数据访问逻辑分离,让代码更清晰、更易维护。下面我从设计思想 → 基本结构 → 示例代码 → 常见变体 → 最佳实践几个方面说明。


一、DAO 的核心思想

DAO 的作用:

  • 封装对**数据库(或其他持久化方式)**的访问细节
  • 向 Service 层提供面向对象的接口
  • 屏蔽底层存储实现(JDBC / MyBatis / JPA / NoSQL)

一句话概括:

DAO 负责“怎么存”,Service 负责“做什么”


二、经典 DAO 设计结构

1️⃣ 典型分层

Controller
   ↓
Service
   ↓
DAO
   ↓
Database

三、一个最基础的 DAO 示例(JDBC)

1. 实体类(Entity)

public class User {
    private Long id;
    private String username;
    private String password;

    // getter / setter
}

2. DAO 接口(面向抽象)

public interface UserDao {
    User findById(Long id);
    List<User> findAll();
    void insert(User user);
    void update(User user);
    void delete(Long id);
}

✅ 好处:以后可以换实现(JDBC → MyBatis → JPA)


3. DAO 实现类(JDBC)

public class UserDaoJdbcImpl implements UserDao {

    private DataSource dataSource;

    public UserDaoJdbcImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public User findById(Long id) {
        String sql = "SELECT id, username, password FROM user WHERE id = ?";
        try (Connection conn = dataSource.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql)) {

            ps.setLong(1, id);
            ResultSet rs = ps.executeQuery();

            if (rs.next()) {
                User user = new User();
                user.setId(rs.getLong("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                return user;
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    // 其他方法省略
}

4. Service 层调用 DAO

public class UserService {

    private UserDao userDao;

    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }

    public User getUser(Long id) {
        return userDao.findById(id);
    }
}

四、DAO 的常见变体

✅ 1. 泛型 DAO(减少重复代码)

public interface BaseDao<T, ID> {
    T findById(ID id);
    List<T> findAll();
    void insert(T entity);
    void update(T entity);
    void delete(ID id);
}
public class UserDaoImpl extends BaseDaoImpl<User, Long> {
}

✅ 适合 CRUD 非常多的场景


✅ 2. MyBatis DAO(接口 + XML)

@Mapper
public interface UserDao {
    User selectById(Long id);
    void insert(User user);
}
<select id="selectById" resultType="User">
    SELECT * FROM user WHERE id = #{id}
</select>

✅ 实际项目中最常见


✅ 3. Spring Data JPA

public interface UserRepository 
        extends JpaRepository<User, Long> {
}

✅ 几乎不用写 SQL


五、DAO 设计的最佳实践 ✅

✅ 1. DAO 只做数据访问

❌ 不要在 DAO 中写业务逻辑

// 错误示例
if (user.getAge() > 18) { ... }

✅ 2. 返回实体对象,而不是 ResultSet

DAO 对上层屏蔽数据库细节


✅ 3. 使用接口 + 实现

  • 方便 mock 测试
  • 方便更换实现

✅ 4. 一个 DAO 对应一个实体

User → UserDao
Order → OrderDao

✅ 5. 异常处理要统一

  • DAO 抛自定义异常
  • 不要直接抛 SQLException
throw new DaoException("查询用户失败", e);

六、DAO vs Repository(常见疑问)

对比 DAO Repository
来源 经典设计模式 DDD
强调 数据访问 领域对象集合
使用 JDBC / MyBatis JPA / Spring Data

实际项目中:

  • MyBatis → 通常叫 DAO
  • JPA → 通常叫 Repository

七、总结一句话

DAO 是“数据库访问的门面”,负责把 SQL / 持久化细节藏起来,只暴露业务需要的数据操作。

如果你愿意,我可以:

  • 帮你设计一个完整项目结构
  • 对比 DAO vs Service
  • 写一个 Spring Boot + MyBatis DAO 示例
  • 或根据你当前技术栈(JDBC / MyBatis / JPA)定制讲解
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手