DAO = Data Access Object
"DB에 직접 접근해서 CRUD 하는 역할만 전담시키는 객체"
전통적인 3계층 구조에서
예전 스타일(특히 순수 JDBC, MyBatis 쓸 때)에는 이렇게 많이 썼다.
public class UserDao {
private final DataSource dataSource;
public UserDao(DataSource dataSource) {
this.dataSource = dataSource;
}
public User findById(Long id) {
// 커넥션 열고, PreparedStatement 만들고, ResultSet 파싱하고...
}
public void save(User user) {
// INSERT 쿼리 실행
}
}
지금 나의 Spring Data JPA의 XXXRepository들이 사실상 DAO 역할을 하는 애들이라고 보면 된다.
public interface TrackingLinkRepository extends JpaRepository<TrackingLink, Long> {
Optional<TrackingLink> findBySlug(String slug);
}
이게 전통적인 용어로는 TrackingLinkDao이다.
스프링 세상(특히 JPA)에서는 보통:
DAO라는 말보다는 Repository 라는 말을 더 많이 씀
이유:
DDD(Domain-Driven Design) 영향
“엔티티의 컬렉션을 캡슐화하는 저장소” 라는 의미 강조
내부의 “데이터 접근 방법(=SQL, JPA, 캐시, 네트워크 등)”은
Repository 안에 숨겨져 있고(캡슐화)
바깥(서비스, 컨트롤러)은 “메서드”만 보는 구조
그래서:
예전: UserDao, OrderDao
요즘: UserRepository, OrderRepository
역할은 비슷하다
→ “DB에 있는 데이터를 가져오고, 저장하고, 지우는 계층”
단지:
"DAO라는 이름을 잘 안쓰지,
DAO에 해당하는 레이어(Repository)는 여전히 필수이다.
DTO = Data Transfer Object
“계층 간에 데이터를 전달할 때 사용하는 순수 데이터용 객체”
보통 게터/세터만 있고, 비즈니스 로직 없음.
요즘 많이 쓰는 DTO 예시:
Request DTO: 클라이언트 → 서버 들어올 때
TrackingLinkCreateRequest
UserSignUpRequest
Response DTO: 서버 → 클라이언트 보낼 때
TrackingLinkResponse
UserProfileResponse
이유:
1) 엔티티를 그대로 노출하면 위험
2) 계층 분리 & 유지보수
그래서 요즘 트렌드는 오히려:
엔티티는 엔티티대로 깔끔하게
요청/응답용 DTO는 DTO대로 깔끔하게
둘 사이 매핑은 Service or Mapper 계층에서 처리
public TrackingLinkResponse toResponse(TrackingLink entity) {
return new TrackingLinkResponse(
entity.getId(),
entity.getSlug(),
entity.getFinalUrl(),
entity.getCreatedAt()
);
}
=> Entity를 밖으로 그대로 내보내지 말고 DTO로 감싸라
예전(고전적인 3계층 + JDBC/MyBatis)
Controller
Service
DAO (직접 구현)
DTO (있긴 한데 엔티티와 혼용되는 경우도 많았음)
Entity/VO 같은 이름들도 섞임
요즘(Spring + JPA + DDD 영향)
Controller (Web Layer: Request/Response DTO)
Service (비즈니스 로직, 트랜잭션 경계)
Repository (DAO 역할)
Entity (도메인 모델)
DTO (API, View, Command/Query 용도별로 따로 정의)
DAO
요즘은 DTO, DAO 잘 쓰는가