DAO와 Repository
- study
- 2021. 4. 8. 17:31
DAO
- Entity Bean의 퍼시스턴스 지원 기능을 대체하는 동시에 비즈니스 로직과 퍼시스턴스 로직의 명확한 분리를 위해 퍼시스턴스 로직을 캡슐화하고 도메인 레이어에 객체 지향적인 인터페이스를 제공하는 객체를 DAO(Data Access Object) 라고 한다.
- DAO는 데이터 퍼시스턴트의 추상화 이다. 테이블 중심의 데이터베이스와 가깝게 고려 된다. 그래서 DAO는 데이터 베이스 테이블과 매치 된다. 데이터 CRUD를 위한 방법을 제공한다.
도메인 클래스 - User
public class User {
private Long id;
private String userName;
private String firstName;
private String email;
// getters and setters
}
UserDAO
public interface UserDao {
void create(User user);
User read(Long id);
void update(User user);
void delete(String userName);
}
public class UserDaoImpl implements UserDao {
private final EntityManager entityManager;
@Override
public void create(User user) {
entityManager.persist(user);
}
@Override
public User read(long id) {
return entityManager.find(User.class, id);
}
// ...
}
Repository Pattern
public interface UserRepository {
User get(Long id);
void add(User user);
void update(User user);
void remove(User user);
}
public class UserRepositoryImpl implements UserRepository {
private UserDaoImpl userDaoImpl;
@Override
public User get(Long id) {
User user = userDaoImpl.read(id);
return user;
}
@Override
public void add(User user) {
userDaoImpl.create(user);
}
// ...
}
- 현재 User 도메인이 빈약한 도메인이기 때문에 DAO와 레포지토리의 구현이 유사하다.
- DAO는 퍼시스턴스 레이어에 속한다. 반면 REPOSITORY의 인터페이스는 도메인 레이어에 속한다. DAO는 DB와 가까운 존재고, Repository는 도메인과 가까운 존재.
도메인이 복잡해 진다면?
- 트위터 트윗, 페이스북 게시물 등을 종합해 사용자의 소셜 미디어 프로필을 준비하고 싶다면?
public class Tweet {
private String email;
private String tweetText;
private Date dateCreated;
// getters and setters
}
public interface TweetDao {
List<Tweet> fetchTweets(String email);
}
public class TweetDaoImpl implements TweetDao {
@Override
public List<Tweet> fetchTweets(String email) {
List<Tweet> tweets = new ArrayList<Tweet>();
//call Twitter API and prepare Tweet object
return tweets;
}
}
- 여기서 트윗 데이터는 DB가 아니라 트위터 3rd party API를 통해 가져온다.
public class UserSocialMedia extends User {
private List<Tweet> tweets;
// getters and setters
}
public class UserRepositoryImpl implements UserRepository {
private UserDaoImpl userDaoImpl;
private TweetDaoImpl tweetDaoImpl;
@Override
public User get(Long id) {
UserSocialMedia user = (UserSocialMedia) userDaoImpl.read(id);
List<Tweet> tweets = tweetDaoImpl.fetchTweets(user.getEmail());
user.setTweets(tweets);
return user;
}
}
- UserRepository에서는 UserDAO와 TweetDAO를 사용하여 사용자 데이터와 트위터 데이터를 가져온다.
- 두 가지 데이터를 조합하여 도메인 객체인 UserSocialMedia를 제공한다.
- 저장소는 다양한 소스에서 데이터에 접근하기 위해 여러 DAO를 가질 수 있다.
DAO와 REPOSITORY의 차이점
- DAO는 데이터 지속성의 추상화이지만 레포지토리는 객체 컬렉션의 추상화이다.
- DAO는 데이터 소스에 가까운 더 하위 개념이다. 그러나 레포지토리는 도메인 개체에 가까운 상위개념이다.
- DAO는 쿼리를 숨기는 데이터 매핑/액세스 계층이다. 그러나 레포지토리는 도메인과 데이터 액세스 사이의 계층으로 데이터를 수집하고 도메인 개체를 준비하는 복잡성을 숨긴다.
- DAO에서 레포지토리를 사용 할 수 없다. 그러나 레포지토리에서는 기본 스토리지에 접근하기 위해 DAO를 사용할 수 있다.
- 빈약한 도메인이 있다면 레포지토리와 DAO는 같은 역할을 한다.
- 빈약한 도메인 모델은 도메인 객체들에 비즈니스 로직이 거의 없거나 아예 없는 소프트 웨어 도메인 모델 이다.
결론
레포지토리에서는 기본 스토리지에 접근하기 위해 DAO를 사용할 수 있다. 그리고 레포지토리는 도메인 개체에 가까운 상위 개념이다. 이 두문장이 레포지토리와 DAO의 차이를 이해하는데 많은 도움을 줬다.
일대일 테이블로 매핑되는 DAO와 여러 DAO를 통해 데이터를 가져와 도메인 객체를 만들어 제공하는 것이 레포지토리의 역할이다.
참고
www.baeldung.com/java-dao-vs-repository
github.com/msbaek/memo/blob/master/dao-vs-repository.md
blog.daum.net/question0921/797
egloos.zum.com/aeternum/v/1160846
'study' 카테고리의 다른 글
Spring 동작원리 (2) | 2021.04.30 |
---|---|
Spring @Valid, @Validated Annotation (2) | 2021.04.22 |
Spring이란? (0) | 2021.04.20 |
Field Injection 왜 권장하지 않을까? (0) | 2021.04.19 |
[Spring]Request Mapping (2) | 2021.04.13 |