[데이터베이스] DAO, Repository 패턴 비교
[데이터베이스] DAO, Repository 패턴 비교 — #자바스프링 #javaspring #DAO #repositorypattern #영속성레이어 #데이터베이스 #개발자의도구들 🚨...
#자바스프링 #javaspring #DAO #repositorypattern #영속성레이어 #데이터베이스 #개발자의도구들
🚨📝 📖 📒
AI스쿨 msa기반 java 백엔드 코스 중에 공부한 내용을 작성하였습니다
\* 현재 Spring 프로젝트를 진행 중입니다. 전체적인 목차를 보시려면 여기를 눌러주세요.
영속성 레이어
이전글에서 JPA에 대해서 알아봤으니 이제는 영속성 레이어의 패턴에 대해 좀 더 심도있게 알아볼 필요가 있겠습니다. JAVA 에서는 persistency layer를 따로 두어 데이터를 관리합니다. 이렇게하는 이유는 매우 다양한데 간단하게 요약하자면, 데이터 무결성, 보안성, 성능 개선, 유지 보수의 용이성 등이 있습니다.
지금 당장에 하나 하나 알아보기에는 무리고 알아본다고 해도 잘 와닿지 않을 가능성이 큽니다. 그래서 그냥 받아들이는게 맞는 것 같습니다. 디자인 패턴이라는건 결국 오랜시간 개발자들이 경험하며 최적화된 설계를 위한 노력에 기반하고 있으닌깐, 그들의 경험을 믿어보는 것이 중요합니다.(때론 틀릴 수도 있지만요)
그래서 영속성 레이어가 무엇이냐하면은 MVC패턴에서 데이터를 처리하고 관리하는 Layer를 구분한 것 처럼, Persistency Layer를 클래스로 분리해 데이터를 관리하는 계층을 말합니다.
앞서 공부한 JPA역시 Persistenc Layer라고 말할 수 있습니다.
Design Pattern
지금부터 하는 이야기는 모두 Persistency Layer를 구현하는 디자인 패턴에 관한 이야기입니다.
DAO
DAO 패턴은 The Data Access Object Pattern으로 가장 저수준의 persistence layer pattern이 되겠습니다. 데이터베이스의 테이블과 매칭되게 클래스를 구성하며, 가장 기본적인 연산인 CRUD 를 지원합니다.
| @Entitypublic class User { @Id @GeneratedValue(strategy = GenerationType.IDENTIFY) private long id; private String firstName; private String lastName;} |
|---|
| public interface UserDao { void create(User user); User read(Long id); void update(User user); void delete(String userName);} |
|---|
public class UserDaoImp1 implements UserDao { @PersistenceContext private EntityManger entityManager; @Override public User findById(Long id) { return entityManger.find(User.class, id); } @Override public void save(User user) { entityManger.persist(user); } @Override public void update(User user) { entityManger.merge(user); } @Override public void delete(User user) { entityManger.remove(entityManger.contains(user) ? user : entityManger.merge(user)); } @Override public List<User> findByLastName(String lastName) { TypedQuery<User> query = entityManger.createQuery( "SELECT u FROM User u Where u.lastName = :lastName", User.class); query.setParmeter("lastName", lastName); return query.getResultList(); }} |
|---|
다른 패턴들도 마찬가지이지만, 인터페이스를 정의하고나서 Impl 클래스를 따로 선언하여 구체적으로 구현하는 형태를 취하고 있습니다.
Repository Desgin pattern
DAO보다 높은 수준의 Respository pattern이 있습니다. DAO는 보통 CRUD를 지원하는데, Repository Pattern은 DAO의 CRUD 기능과 더불어 좀 더 복잡하고 핵심적이 로직을 처리합니다.
도서관의 비유를 들자면 우리가 찾는 책이 데이터라고 합시다. 우리는 책을 직접 찾을 수도 있겠지만, 수많은 책이있는 도서관에서 원하는 책을 찾기란 쉽지 않습니다. 이때 우리는 사서에게 물어보는데, 사서에게 물어보면, 더 이상 책이 어디에 있는지 직접 고민하지 않아도 됩니다. 이 때 사서의 역할이 Repository의 역할이라고 할 수 있습니다.
| public interface TextRepository { TextEntity findById(long id); void save(TextEntity text); void delete(TextEntity text);} |
|---|
| package com.example.webserver.repository;import com.example.webserver.model.TextEntity;import jakarta.persistence.EntityManager;import jakarta.persistence.PersistenceContext;public class TextRepositoryImpl implements TextRepository { @PersistenceContext private EntityManager entityManager; @Override public TextEntity findById(Long id) { return entityManager.find(TextEntity.class, id); } @Override public void save(TextEntity text) { if (text.getId() == null) { entityManager.persist(text); // 새로운 엔티티 저장 } else { entityManager.merge(text); // 기존 엔티티 업데이트 } } @Override public void delete(TextEntity text) { if (entityManager.contains(text)) { entityManager.remove(text); } else { TextEntity managedText = findById(text.getId()); if (managedText != null) { entityManager.remove(managedText); } } }} |
|---|
JPA를 사용하여 구현하고 있기 대문에, DB 로직에 관해서는 entityManger를 직접 활용하여 처리하면 됩니다.
참고로 이미 JPA를 사용하는 시점부터 persistence layer pattern을 적용하고 있다고 보시면 될 것 같습니다.

