이 영역을 누르면 첫 페이지로 이동
천천히 꾸준히 조용히 블로그의 첫 페이지로 이동

천천히 꾸준히 조용히

페이지 맨 위로 올라가기

천천히 꾸준히 조용히

천천히 꾸준히 조용히.. i3months 블로그

[Spring Database] Spring Data JPA

  • 2022.09.11 18:09
  • Spring/Spring Database
반응형

 

 

 

스프링 데이터 JPA 기술의 가장 대표적인 기능은 두 가지이다.

 

1. 공통 인터페이스

2. 쿼리 메서드

 

 

 

 

 

 

JpaRepository 인터페이스는 기본적인 CRUD 및 공통화가 가능한 기능들을 모두 제공한다.

 

JpaRepository 인터페이스를 사용할 리포지토리에서 상속받고(extends), 제네릭에 관리할 <Entity, EntityId>를 입력해주면 스프링 데이터 JPA 기술 내부에서 프록시 기술을 통해 구현 클래스가 생성된다.

 

만들어진 구현 클래스의 인스턴스는 스프링 빈으로 등록되고, 개발자는 구현 클래스를 신경쓰지 않고 JpaRepository 인터페이스가 제공하는 기술을 사용할 수 있다.

 

 

인터페이스에 메서드만 적어두면 스프링 데이터 JPA 기술이 메서드 이름을 분석해 쿼리를 자동으로 만들고 실행해준다.

 

JPA만 사용했을 경우 복잡한 쿼리를 보낼 때 JPQL을 직접 작성하고 파라미터 바인딩도 해 줘야 했지만,

스프링 데이터 JPA는 메서드 이름을 분석해 필요한 JPQL을 만들고 실행해준다.

(메서드 이름은 규칙에 맞게 작성해야 한다)

 

직접 JPQL을 작성하고 싶을 때는 @Query 애너테이션에 JPQL을 넣어 주면 된다.

 

 

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);
}

 

 

상품을 이름으로 검색하거나 가격으로 검색하는 기능은 공통으로 처리할 수 없다.

쿼리 메서드 혹은 @Query 애너테이션을 사용하자.

 

@Query 애너테이션을 사용하지 않는 경우 스프링 데이터 JPA가 메서드 이름을 분석해 JPQL을 만들어서 실행한다.

애너테이션을 사용해 쿼리를 직접 사용할 경우 @Param 애너테이션으로 파라미터를 명시적으로 바인딩 해 주자.

 

 

 

 

ItemService는 ItemRepository에 의존한다.

 

ItemService의 수정 없이 SpringDataJpaItemRepository를 사용하기 위해 JpaItemRepositoryV2를 도입하자.

JpaItemRepositoryV2는 ItemRepository의 구현체이고, SpringDataJpaItemRepository를 사용한다.

 

JpaItemRepositoryV2를 어댑터처럼 사용한다.

 

 

@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.findItems("%" + itemName + "%", maxPrice);
        } else if (StringUtils.hasText(itemName)) {
            return repository.findByItemNameLike("%" + itemName + "%");
        } else if (maxPrice != null) {
            return repository.findByPriceLessThanEqual(maxPrice);
        } else {
            return repository.findAll();
        }
    }
}

 

 

스프링 데이터 JPA 기술이 제공하는 메서드들을 사용해 작업을 처리한다.

혹시나 예외가 발생해도 프록시에서 예외를 변환 해 주기 때문에 @Repository 애너테이션에 상관없이 예외가 변환된다.

 

findAll 부분은 공통으로 제공하는 기능이 아니라서 별도로 작성한 메서드를 사용한다.

조건이 2개인데도 참 복잡하다. 메서드 이름도 길어지고.. 조건이 더 많아질수록 문제가 심각해진다.

 

스프링 데이터 JPA는 동적 쿼리에 관련된 지원이 약하다. 추후 QueryDSL 기술을 사용해 동적 쿼리 부분을 개선해보자.

반응형
저작자표시 (새창열림)

'Spring > Spring Database' 카테고리의 다른 글

[Spring Database] 트랜잭션  (0) 2022.09.13
[Spring Database] QueryDSL  (1) 2022.09.11
[Spring Database] JPA 적용  (0) 2022.09.10
[Spring Database] JPA  (1) 2022.09.09
[Spring Database] MyBatis  (0) 2022.09.09

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Spring Database] 트랜잭션

    [Spring Database] 트랜잭션

    2022.09.13
  • [Spring Database] QueryDSL

    [Spring Database] QueryDSL

    2022.09.11
  • [Spring Database] JPA 적용

    [Spring Database] JPA 적용

    2022.09.10
  • [Spring Database] JPA

    [Spring Database] JPA

    2022.09.09
다른 글 더 둘러보기

정보

천천히 꾸준히 조용히 블로그의 첫 페이지로 이동

천천히 꾸준히 조용히

  • 천천히 꾸준히 조용히의 첫 페이지로 이동

검색

방문자

  • 전체 방문자
  • 오늘
  • 어제

카테고리

  • 분류 전체보기 (668) N
    • Algorithm (205)
      • Data Structure (5)
      • Theory && Tip (33)
      • Baekjoon (166)
      • ALGOSPOT (1)
    • Spring (123)
      • Spring (28)
      • Spring Web MVC (20)
      • Spring Database (14)
      • Spring Boot (6)
      • Spring 3.1 (11)
      • Spring Batch (6)
      • Spring Security (16)
      • JPA (12)
      • Spring Data JPA (5)
      • QueryDSL (4)
      • eGovFramework (1)
    • Programming Language (74)
      • C (25)
      • C++ (12)
      • Java (19)
      • JavaScript (15)
      • Python (1)
      • PHP (2)
    • Computer Science (142)
      • Machine Learning (38)
      • Operating System (18)
      • Computer Network (28)
      • System Programming (22)
      • Universial Programming Lang.. (8)
      • Computer Architecture (4)
      • Compiler Design (11)
      • Computer Security (13)
    • Database (21)
      • Database (7)
      • MySQL (3)
      • Oracle (3)
      • Redis (5)
      • Elasticsearch (3)
    • DevOps (20)
      • Docker && Kubernetes (8)
      • Jenkins (4)
      • Amazon Web Service (8)
    • Mobile (28)
      • Android (21)
      • Flutter (7)
    • 💡 솔루션 (16)
    • 👥 모각코 (6)
    • 💬 기록 (6) N
    • 📚 공부 (2)
    • -------------- (25)

최근 글

나의 외부 링크

메뉴

  • 홈
반응형

정보

i3months의 천천히 꾸준히 조용히

천천히 꾸준히 조용히

i3months

블로그 구독하기

  • 구독하기
  • RSS 피드

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. Copyright © i3months.

티스토리툴바