Data Access Object (DAO):抽象封裝底層資料存取 (SQL/NoSQL/檔案),向上層提供**面向物件的 CRUD 介面**。屬於**資料層**,是企業級分層架構基石。
| 層次 | 職責 | 典型技術 | 與 DAO 關係 |
|---|---|---|---|
| **客戶層** | 瀏覽器、App、第三方 API | HTTP/REST/gRPC | 無感知 |
| **表示層** | Controller、View (JSP/Thymeleaf/React) | Spring MVC、Struts | 調用 Service,不直接碰 DAO |
| **業務層 (Service/BO)** | 事務邊界、業務規則編排、多 DAO 組合 | Spring @Transactional、EJB | **DAO 的直接消費者** |
| **資料層 (DAO)** | 單表/單實體原子操作:增刪改查、分頁、批次 | JPA/Hibernate、MyBatis、JdbcTemplate | 核心實現 |
| **資源層** | 資料庫、檔案系統、快取、搜尋引擎 | MySQL、Redis、ES、S3 | DAO 底層依賴 |

get/set、Serializable、JPA 註解。save()、update()、delete()、findById()、findAll()...DAOFactory.getUserDAO() 返回 Proxy 包裝後的 DAO 實例,上層無感知具體實現。public class UserVO implements Serializable {
private Long id; private String username; private String email;
// getters/setters
}
public interface UserDAO {
void save(UserVO user);
void update(UserVO user);
void delete(Long id);
UserVO findById(Long id);
List findAll();
}
public class UserDAOImpl implements UserDAO {
private Connection conn;
public UserDAOImpl(Connection conn) { this.conn = conn; } // 連接由 Proxy 注入
// 實現 CRUD 方法...
}
public class UserDAOProxy implements UserDAO {
private UserDAO target;
public UserDAOProxy() { this.target = new UserDAOImpl(null); }
public void save(UserVO user) {
Connection conn = DBConnection.getConnection();
try {
((UserDAOImpl)target).setConnection(conn);
target.save(user);
conn.commit();
} catch (Exception e) { conn.rollback(); throw new RuntimeException(e); }
finally { DBConnection.close(conn); }
}
// 其他方法同理...
}
public class DAOFactory {
public static UserDAO getUserDAO() { return new UserDAOProxy(); }
// 其他 DAO...
}
public class UserService {
private UserDAO userDAO = DAOFactory.getUserDAO();
public void register(UserVO user) {
// 業務規則:用戶名唯一、密碼加密、發送歡迎郵件...
userDAO.save(user);
}
}
| 時代 | 特徵 | 代表技術 |
|---|---|---|
| 手工 JDBC + DAO 六件套 | 樣板代碼多、連接管理易漏、SQL 分散 | 早期 J2EE、Struts 1 |
| Hibernate DAO | ORM 映射、Session 管理、HQL | Hibernate 3/4、Spring HibernateTemplate |
| Spring Data JPA | 接口即實現、方法名查詢、Specification 動態查詢 | interface UserRepo extends JpaRepository |
| MyBatis Mapper | SQL 完全控制、XML/註解映射、動態 SQL 強大 | @Mapper interface UserMapper |
| 現代最佳實踐 | **領域驅動設計 (DDD) + Repository 模式** 領域層定義 Repository 接口,基礎設施層實現 (JPA/MyBatis) | Spring Boot 3、Quarkus、Micronaut |
save/update/delete 往往不夠用,業務查詢仍需自定義。**接口細分、按聚合根劃分 Repository**。finally { close() }。**優先用框架聲明式事務**。