ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링 DB 데이터접근 기술 - 스프링데이터 JPA
    Spring-Boot/스프링 DB 2편 - 데이터 접근 기술 2022. 9. 22. 18:19

    스프링 데이터 JPA 주용기능

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

     

    공통 인터페이스 기능

    - `JpaRepository` 인터페이스를 통해서 기본적인 CRUD 기능 제공한다

    - 공통화 가능한 기능이 거의 모두 포함되어 있다

    - `CrudRepository`에서 `findOne()` → `findById()`로 변경

     

    * JpaRepository 사용법 *

    public interface ItemRepository extends JpaRepository<Member, Long> {
    }

    - `JpaRepository` 인터페이스를 인터페이스 상속 받고, 제네릭에 관리할 `<엔티티, 엔티티ID>`를 주면된다

    - 그러면 `JpaRepository`가 제공하는 기본 CRUD 기능을 모두 사용가능

     

    * 스프링 데이터 JPA가 구현 클래스를 대신 생성 *

    - `JpaRepository` 인터페이스만 상속받으면 스프링 데이터 JPA가 프록시 기술을 사용해서 구현 클래스를 만들어준다.

       그리고 만든 구현 클래스의 인스턴스를 만들어서 스프링 빈으로 등록

    - 따라서 개발자는 구현 클래스 없이 인터페이스만 만들면 기본 CRUD 기능을 사용할 수 있다.

     

    쿼리 메서드 기능

    - 스프링 데이터 JPA는 인터페이스에 메서드만 적어두면 메서드 이름을 분석해서 쿼리를 자동으로 만들고 실행해주는 기능을 제공

     

    * 순수 JPA 리포지토리 *

    public List<Member> findByUsernameAndAgeGreaterThan(String username, int age) {
        return em.createQuery("select m from Member m where m.username = :username and m.age > :age")
                	.setParameter("username",username)
                    .setParameter("age",age)
                    .getResultList();
    }

    - 순수 JPA를 사용하면 직접 JPQL을 작성하고, 파라미터도 직접 바인딩해야한다.

     

    * 스프링 데이터 JPA *

    public interface MemberRepository extends JpaRepository<Member, Long> {
        List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
    }

    - 스프링 데이터 JPA는 메서드 이름을 분석해서 필요한 JPQL을 만들고 실행해준다. 물론 JPQL은 JPA가 SQL로 번역해서 실행

    - 물론 그냥 아무 이름이나 사용하는 것은 아니고 다음과 같은 규칙을 따라야 한다.

     

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

    - 조회 : `find...By`, `read...By`, `query...By`, `get...By`

        ㆍ예:) `findHelloBy` 처럼 ...에 식별하기 위한 내용이 들어가도 된다.

    - COUNT : `count...By` 반환타입 `long`

    - EXISTS : `exists...By` 반환타입 `boolean`

    - 삭제 : `delete...By`, `remove...By` 반환타입 `long`

    - DISTINCT : `findDistinct`, `findMemberDistinctBy`

    - LIMIT : `findFirst3`, `findFirst`, `findTop`, `findTop3`

     

    * JPQL 직접 사용하기 *

    public interface SpringDataJpaItemRepository extends JpaRepository<Item, Long> {
        // 쿼리 메서드 기능
        List<Item> findByItemNameLike(String itemName);
        
        // 쿼리 직접 실행
        @Query("select i from Item i where i.itemName like :itemName and i.price <= :price")
        List<Item> findItem(@Param("itemName") String itemName, @Param("price") Integer price);
    }

    - 쿼리 메서드 기능 대신에 직접 JPQL을 사용하고 싶을 때는 `@Query`와 함께 JPQL을 작성하면 된다. 

      이때는 메서드 이름으로 실행하는 규칙은 무시된다.

    - 참고로 스프링 데이터 JPA는 JPQL뿐만 아니라 JPA의 네이티브 쿼리 기능도 지원하는데, JPQL 대신에 SQL을 직접 작성

     

    *중요*

    - 스프링 데이터 JPA는 JPA를 편리하게 사용하도록 도와주는 도구이다. 따라서 JPA 자체를 잘 이해하는 것이 가장 중요


    스프링 데이터 JPA 적용 

    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 기능 사용가능

    - 그런데 이름으로 검색하거나, 가격으로 검색하는 기능은 공통으로 제공할 수 있는 기능이 아니다. 따라서 쿼리 메서드 기능을 사용하거나 `@Query`를 사용해서 직접 쿼리를 실행

     

    * 참고 *

    - 스프링 데이터 JPA도 `Example` 이라는 기능으로 약간의 동적 쿼리를 지원하지만, 실무에서 사용하기는 기능이 빈약하다.

    - 실무에서 JPQL 동적쿼리는 Querydsl을 사용하는 것이 좋다.

     

    * 메서드 이름으로 쿼리를 실행하는 기능의 단점 *

    1. 조건이 많으면 메서드 이름이 너무 길어진다

    2. 조인 같은 복잡한 조건을 사용할 수 없다

    - 메서드 이름으로 쿼리를 실행하는 기능은 간단한 경우에는 매우 유용하지만, 복잡해지면 직접 JPQL 쿼리를 작성하는 것이 좋다.

     

    - 쿼리를 직접 실행할려면 `@Query` 애노테이션을 사용

    - 메서드 이름으로 쿼리를 실행할 때는 파라미터를 순서대로 입력하면 되지만, 쿼리를 직접 실행할 때는 파라미터를 명시적으로 바인딩해야 한다.

    - 파라미터 바인딩은 `@Param("itemName")` 애노테이션을 사용하고, 애노테이션의 값에 파라미터 이름을 주면 된다.

     

    * 예외 변환 *

    - 스프링 데이터 JPA도 스프링 예외 추상화를 지원한다. 

    - 스프링 데이터 JPA가 만들어주는 프록시에서 이미 예외 변환을 처리하기 때문에 `@Repository` 와 관계없이 예외가 변환

    댓글

Designed by Tistory.