데이터베이스발행일 2024. 7. 18.원본 https://blog.naver.com/jword_/223517142489 ↗

[데이터베이스] DAO, Repository 패턴 비교

[데이터베이스] DAO, Repository 패턴 비교 — #자바스프링 #javaspring #DAO #repositorypattern #영속성레이어 #데이터베이스 #개발자의도구들 🚨...

#DataBase#Naver Blog

#자바스프링 #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을 적용하고 있다고 보시면 될 것 같습니다.

​