[SpringBoot] DAO 설계
DAO
데이터베이스에 접근하기 위한 로직을 관리하기 위한 객체, 비즈니스 로직의 동작 과정에서 데이터를 조작하는 기능은 DAO 객체가 수행하지만 스프링 데이터 JPA에서 DAO의 개념은 리포지토리가 대체하고 있다.
1. DAO 클래스 생성
DAO 클래스는 일반적으로 인터페이스-구현체 구성으로 생성한다. 서비스 레이어에 DAO 객체를 주입받을 때 인터페이스를 선언하는 방식으로 구성한다. data.dao.impl 구조로 패키지를 생성한 후 dao 패키지와 impl 패키지에 ProductDAO 인터페이스와 ProductDAOImpl 클래스를 생성한다.
2. ProductDAO 인터페이스
아래와 같이 인터페이스 설계를 해준다.
public interface ProductDAO {
Product insertProduct(Product product);
Product selectProduct(Long number);
Product updateProductName(Long number, String name) throws Exception;
void deleteProduct(Long number) throws Exception;
}
3. ProductDAOImpl(ProductDAO 인터페이스 구현체)
ProductDAO 인터페이스를 상속받는다. 다중 상속이므로 인터페이스에서 구현된 insertProduct, selectProduct, UpdateProductName, deleteProduct 메서드 모두 @Override 어노테이션을 통해 재정의해준다.
@Component
public class ProductDAOImpl implements ProductDAO {
private final ProductRepository productRepository;
@Autowired
public ProductDAOImpl(ProductRepository productRepository) {
this.productRepository = productRepository;
}
@Override
public Product insertProduct(Product product) {
Product savedProduct = productRepository.save(product);
return savedProduct;
}
@Override
public Product selectProduct(Long number) {
Product selectedProduct = productRepository.getReferenceById(number);
return selectedProduct;
}
@Override
public Product updateProductName(Long number, String name) throws Exception {
Optional<Product> seletedProduct = productRepository.findById(number);
Product updatedProduct;
if(seletedProduct.isPresent()) {
Product product = seletedProduct.get();
product.setName(name);
product.setUpdatedAt(LocalDateTime.now());
updatedProduct = productRepository.save(product);
} else {
throw new Exception();
}
return updatedProduct;
}
@Override
public void deleteProduct(Long number) throws Exception {
Optional<Product> selectedProduct = productRepository.findById(number);
if(selectedProduct.isPresent()) {
Product product = selectedProduct.get();
productRepository.delete(product);
} else {
throw new Exception();
}
}
}
ProductDAOImpl 클래스를 스프링이 관리하는 빈으로 등록하려면 @Component 또는 @Service 어노테이션을 지정해야 한다. 빈으로 등록된 객체는 다른 클래스가 인터페이스를 가지고 @Autowired 어노테이션을 통해 의존성을 주입받을 때 이 구현체를 찾아 주입하게 된다.
3-1. insertProduct() 메서드
@Override
public Product insertProduct(Product product) {
Product savedProduct = productRepository.save(product);
return savedProduct;
}
JPA에서 기본으로 제공하는 save 메서드를 활용하여 Product 생성자 savedProduct에 productRepository의 레포지토리에 product를 저장한다.
3-2. selectProduct() 메서드
@Override
public Product selectProduct(Long number) {
Product selectedProduct = productRepository.getReferenceById(number);
return selectedProduct;
}
getReferenceById로 해당 number와 일치하는 데이터를 조회하여 selectedProduct에 저장한다.
3-3. updateProductName() 메서드
@Override
public Product updateProductName(Long number, String name) throws Exception {
Optional<Product> seletedProduct = productRepository.findById(number);
Product updatedProduct;
if(seletedProduct.isPresent()) {
Product product = seletedProduct.get();
product.setName(name);
product.setUpdatedAt(LocalDateTime.now());
updatedProduct = productRepository.save(product);
} else {
throw new Exception();
}
return updatedProduct;
}
* Optional<T>는 null이 올 수 있는 값을 감싸는 Wrapper 클래스로, 참조하더라도 NPE가 발생하지 않도록 도와준다.
findById 메서드를 통해 데이터베이스에서 값을 가져오면 가져온 객체가 영속성 컨텍스트에 추가된다. updatedProduct라는 Product 엔티티의 생성자를 생성하고 selectedProduct가 있으면 product 생성자에 selectedProduct를 가져와서 저장하고 product 생성자의 name과 updatedAt를 set해준다. product 생성자를 updatedProduct에 저장해준다.
3-4. deleteProduct() 메서드
@Override
public void deleteProduct(Long number) throws Exception {
Optional<Product> selectedProduct = productRepository.findById(number);
if(selectedProduct.isPresent()) {
Product product = selectedProduct.get();
productRepository.delete(product);
} else {
throw new Exception();
}
}
updateProduct 메서드와 동일하게 Optional<>로 데이터가 없어 에러가 발생하지 않도록 방지하고, selectedProduct가 있으면 product 생성자에 selectedProduct를 가져와 저장하고 productRepository의 delete 메서드를 활용하여 product를 삭제해준다.
참고 문헌: 스프링 부트 핵심 가이드(스프링 부트를 활용한 애플리케이션 개발 실무)
http://www.yes24.com/Product/Goods/110142898
스프링 부트 핵심 가이드 - YES24
입문자의 눈높이에 맞춰 차근차근 따라 하면서 배우는 스프링 부트 입문서!《스프링 부트 핵심 가이드》는 스프링 부트 기반의 애플리케이션을 개발할 때 필요한 기초적인 내용들을 소개하고,
www.yes24.com