温馨提示×

温馨提示×

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

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

Java DAO 数据访问对象如何封装

发布时间:2026-07-24 21:41:48 来源:亿速云 阅读:103 作者:小樊 栏目:编程语言

在 Java 中,**DAO(Data Access Object,数据访问对象)**的核心思想是:

把对数据库的访问逻辑从业务逻辑中分离出来,统一封装在 DAO 层。

下面从设计思想 → 典型结构 → 示例代码 → 常见封装方式一步步说明。


一、DAO 的核心作用

DAO 主要解决以下问题:

  • ✅ 屏蔽底层数据库细节(JDBC / MyBatis / JPA)
  • ✅ 提供统一的增删改查接口
  • ✅ 降低业务层与数据库耦合
  • ✅ 便于维护和替换持久层技术

二、DAO 的典型分层结构

service  →  dao  →  database
  • Service:业务逻辑
  • DAO:数据访问
  • Entity / Model:数据库表映射对象

三、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();

    int insert(User user);

    int update(User user);

    int delete(Long id);
}

✅ 好处:

  • 业务层只依赖接口
  • 方便切换实现(JDBC / MyBatis / JPA)

3️⃣ DAO 实现类(JDBC)

public class UserDaoImpl implements UserDao {

    private Connection connection;

    public UserDaoImpl(Connection connection) {
        this.connection = connection;
    }

    @Override
    public User findById(Long id) {
        String sql = "SELECT * FROM user WHERE id = ?";
        try (PreparedStatement ps = connection.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) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public int insert(User user) {
        String sql = "INSERT INTO user(username, password) VALUES (?, ?)";
        try (PreparedStatement ps = connection.prepareStatement(sql)) {
            ps.setString(1, user.getUsername());
            ps.setString(2, user.getPassword());
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    // delete / update / findAll 类似
}

四、DAO 的进一步封装(通用 DAO)

1️⃣ 通用 DAO 接口

public interface BaseDao<T, ID> {
    T findById(ID id);
    List<T> findAll();
    int save(T entity);
    int update(T entity);
    int delete(ID id);
}

2️⃣ 抽象 DAO 实现(减少重复代码)

public abstract class BaseDaoImpl<T, ID> implements BaseDao<T, ID> {

    protected Class<T> entityClass;

    public BaseDaoImpl(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    // 公共方法(如映射 ResultSet → Entity)
}

✅ 实际项目中 MyBatis / JPA 已经帮你做了这部分


五、使用 MyBatis 的 DAO 封装(最常见)

1️⃣ Mapper 接口(DAO)

@Mapper
public interface UserDao {
    User selectById(Long id);
    int insert(User user);
}

2️⃣ XML / 注解 SQL

<select id="selectById" resultType="User">
    SELECT * FROM user WHERE id = #{id}
</select>

✅ MyBatis 中 Mapper = DAO


六、使用 JPA 的 DAO 封装

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

✅ 连实现类都不用写


七、DAO 封装的最佳实践 ✅

✅ DAO 层只做数据访问,不做业务逻辑
✅ 使用接口 + 实现类(或 Mapper)
✅ 一个 DAO 对应一个实体
✅ 不要在 DAO 中写事务控制(交给 Service)
✅ 统一异常处理(如 DAOException)


八、DAO vs Mapper vs Repository

名称 说明
DAO 传统数据访问对象
Mapper MyBatis 的 DAO
Repository JPA / Spring Data

九、总结一句话

DAO 的本质:把“怎么取数据”封装起来,让业务层只关心“要什么数据”。

如果你愿意,我可以:

  • ✅ 写一个 完整 DAO + Service 示例
  • ✅ 对比 JDBC / MyBatis / JPA DAO
  • ✅ 帮你设计 企业级 DAO 结构

你现在是 学习阶段 还是 实际项目使用?

向AI问一下细节

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

AI
助
手