[Spring] 스프링 DB 2편 06

알재·2023년 12월 5일

스프링 DB

목록 보기
12/17

김영한님의 스프링 DB 2편 을 공부하여 정리한 글입니다.

스프링 데이터 JPA 주요 기능

스프링 데이터 JPA는 JPA를 편리하게 사용할 수 있도록 도와주는 라이브러리이다.

공통 인터페이스 기능

  • JpaRepository 인터페이스를 통해서 기본적인 CRUD 기능 제공한다.
  • 공통화 가능한 기능이 거의 모두 포함되어 있다.

  • JpaRepository 인터페이스만 상속받으면 스프링 데이터 JPA가 프록시 기술을 사용해서 구현 클래스를
    만들어준다. 그리고 만든 구현 클래스의 인스턴스를 만들어서 스프링 빈으로 등록한다.

쿼리 메서드 기능

스프링 데이터 JPA는 인터페이스에 메서드만 적어두면, 메서드 이름을 분석해서
쿼리를 자동으로 만들고 실행해주는 기능을 제공한다.
쿼리 메서드 기능 대신에 직접 JPQL을 사용하고 싶을 때는 @Query 와 함께 JPQL을 작성하면 된다.
이때는 메서드 이름으로 실행하는 규칙은 무시된다.

스프링 데이터 JPA가 제공하는 쿼리 메소드 기능

  • 조회: find…By , read…By , query…By , get…By
  • COUNT: count…By 반환타입 long
  • EXISTS: exists…By 반환타입 boolean
  • 삭제: delete…By , remove…By 반환타입 long
  • DISTINCT: findDistinct , findMemberDistinctBy
  • LIMIT: findFirst3 , findFirst , findTop , findTop3

스프링 데이터 JPA 적용1

JpaRepository

public interface SpringDataJpaItemRepository extends JpaRepository<Item, Long> {

    List<Item> findByItemNameLike(String itemName);
    List<Item> findByPriceLessThanEqual(Integer price);

    //쿼리 메서드
    List<Item> findByItemNameLikeAndPriceLessThanEqual(String itemName, Integer price);

    //쿼리 직접 실행
    @Query("select i from Item i where i.itemName like :itemName and i.price <= :price")
    List<Item> findItems(@Param("itemName") String itemName,@Param("price") Integer price);
}
  • 스프링 데이터 JPA가 제공하는 JpaRepository 인터페이스를 인터페이스 상속 받으면 기본적인 CRUD 기능을 사용할 수 있다.
  • 메서드 이름으로 쿼리를 실행하는 기능은 다음과 같은 단점이 있다.
    조건이 많으면 메서드 이름이 너무 길어진다.
    조인 같은 복잡한 조건을 사용할 수 없다.
  • 복잡해지면 직접 JPQL 쿼리를 작성하는 것이 좋다.

스프링 데이터 JPA 적용2

Repository

@Repository
@Transactional
@RequiredArgsConstructor
public class JpaitemRepositoryV2 implements ItemRepository {

    private final SpringDataJpaItemRepository repository;

    @Override
    public Item save(Item item) {
        return repository.save(item);
    }

    @Override
    public void update(Long itemId, ItemUpdateDto updateParam) {
        Item findItem = repository.findById(itemId).orElseThrow();
        findItem.setItemName(updateParam.getItemName());
        findItem.setPrice(updateParam.getPrice());
        findItem.setQuantity(updateParam.getQuantity());
    }

    @Override
    public Optional<Item> findById(Long id) {
        return repository.findById(id);
    }

    @Override
    public List<Item> findAll(ItemSearchCond cond) {
        String itemName = cond.getItemName();
        Integer maxPrice = cond.getMaxPrice();

        if (StringUtils.hasText(itemName) && maxPrice != null) {
//            return repository.findByItemNameLikeAndPriceLessThanEqual("%" + itemName + "%", maxPrice);
            return repository.findItems("%" + itemName + "%", maxPrice);
        } else if (StringUtils.hasText(itemName)) {
            return repository.findByItemNameLike("%" + itemName + "%");
        } else if (maxPrice != null) {
            return repository.findByPriceLessThanEqual(maxPrice);
        } else {
            return repository.findAll();
        }
    }
}

의존관계와 구조

  • ItemService 는 ItemRepository 에 의존하기 때문에 ItemService 에서
    SpringDataJpaItemRepository 를 그대로 사용할 수 없다.

클래스 의존 관계

  • JpaItemRepositoryV2 는 ItemRepository 를 구현한다. 그리고 SpringDataJpaItemRepository 를 사용한다.

런타임 객체 의존 관계

업로드중..

예외 변환

스프링 데이터 JPA도 스프링 예외 추상화를 지원한다.
스프링 데이터 JPA가 만들어주는 프록시에서 이미 예외 변환을 처리하기 때문에,
@Repository 와 관계없이 예외가 변환된다.


profile
저장소

0개의 댓글