You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
JpaRepository 인터페이스를 인터페이스 상속 받고, 제네릭에 관리할 <엔티티, 엔티티ID> 를 주면 된다.
그러면 JpaRepository 가 제공하는 기본 CRUD 기능을 모두 사용할 수 있다.
스프링 데이터 JPA 가 구현 클래스를 대신 생성
JpaRepository 인터페이스만 상속받으면 스프링 데이터 JPA 가 프록시 기술을 사용해서 구현 클래스를 만들어준다. 그리고 만든 구현 클래스의 인스턴스를 만들어서 스프링 빈으로 등록한다.
따라서 개발자는 구현 클래스 없이 인터페이스만 만들면 기본 CRUD 기능을 사용할 수 있다.
쿼리 메서드 기능
스프링 데이터 JPA 는 인터페이스에 메서드만 적어두면, 메서드 이름을 분석해서 쿼리를 자동으로 만들고 실행해주는 기능을 제공한다.
순수 JPA 리포지토리
publicList<Member> findByUsernameAndAgeGreaterThan(Stringusername, intage) {
returnem.createQuery("select m from Member m where m.username = :username and m.age > :age")
.setParameter("username", username)
.setParameter("age", age)
.getResultList();
}
publicinterfaceSpringDataJpaItemRepositoryextendsJpaRepository<Item, Long> {
//쿼리 메서드 기능List<Item> findByItemNameLike(StringitemName);
//쿼리 직접 실행@Query("select i from Item i where i.itemName like :itemName and i.price <= :price")
List<Item> findItems(@Param("itemName") StringitemName, @Param("price")
Integerprice);
}
쿼리 메서드 기능 대신에 직접 JPQL 을 사용하고 싶을 때는 @Query 와 함께 JPQL 을 작성하면 된다. 이 때는 메서드 이름으로 실행하는 규칙은 무시된다.
스프링 데이터 JPA 는 JPQL 뿐만 아니라 JPA 의 네이티브 쿼리 기능도 지원하는데, JPQL 대신에 SQL 을 직접 작성할 수 있다.
4️⃣ 스프링 데이터 JPA 적용1
설정
스프링 데이터 JPA 는 spring-boot-starter-data-jpa 라이브러리를 넣어주면 된다.
build.gradle 추가
//JPA, 스프링 데이터 JPA 추가
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
앞에서 JPA 설정하면서 위의 라이브러리를 넣어주었기 때문에 별도의 라이브러리 설정은 하지 않아도 된다.
여기 라이브러리에는 JPA , 하이버네이트, 스프링 데이터 JPA , 스프링 JDBC 관련 기능도 모두 포함되어 있다.
SpringDataJpaItemRepository
packagehello.itemservice.repository.jpa;
importhello.itemservice.domain.Item;
importorg.springframework.data.jpa.repository.JpaRepository;
importorg.springframework.data.jpa.repository.Query;
importorg.springframework.data.repository.query.Param;
importjava.util.List;
publicinterfaceSpringDataJpaItemRepositoryextendsJpaRepository<Item, Long> {
List<Item> findByItemNameLike(StringitemName);
List<Item> findByPriceLessThanEqual(Integerprice);
//쿼리 메서드 (아래 메서드와 같은 기능 수행)List<Item> findByItemNameLikeAndPriceLessThanEqual(StringitemName, Integerprice);
//쿼리 직접 실행@Query("select i from Item i where i.itemName like :itemName and i.price <= :price")
List<Item> findItems(@Param("itemName") StringitemName, @Param("price") Integerprice);
}
스프링 데이터 JPA 가 제공하는 JpaRepository 인터페이스를 상속 받으면 기본적인 CRUD 기능을 사용할 수 있다.
그런데 이름으로 검색하거나, 가격으로 검색하는 기능은 공통으로 제공할 수 있는 기능이 아니다. 따라서 쿼리 메서드 기능을 사용하거나 @Query 를 사용해서 직접 쿼리를 실행하면 된다.
여기서는 데이터 조건에 따라 4가지로 분류해서 검색한다.
모든 데이터 조회
이름 조회
가격 조회
이름 + 가격 조회
스프링 데이터 JPA 는 동적 쿼리에 약하기 때문에 4가지 상황을 직접 스프링 데이터 JPA 로 구현해보자.
findAll()
코드에선 보이지 않지만 JpaRepository 공통 인터페이스가 제공하는 기능이다.
모든 Item 을 조회한다. select i from Item i 과 같은 JPQL 이 실행된다.
findByItemNameLike()
이름 조건만 검색했을 때 사용하는 쿼리 메서드이다. select i from Item i where i.name like ? 과 같은 JPQL 이 실행된다.
findByPriceLessThanEqual()
가격 조건만 검색했을 때 사용하는 쿼리 메서드이다. select i from Item i where i.price <= ? 과 같은 JPQL 이 실행된다.
findByItemNameLikeAndPriceLessThanEqual()
이름과 가격 조건을 검색했을 때 사용하는 쿼리 메서드이다. select i from Item i where i.itemName like ? and i.price <= ? 와 같은 JPQL 이 실행된다.
findItems()
메서드 이름으로 쿼리를 실행하는 기능은 다음과 같은 단점이 있다.
조건이 많으면 메서드 이름이 너무 길어진다.
조인 같은 복잡한 조건을 사용할 수 없다.
메서드 이름으로 쿼리를 실행하는 기능은 간단한 경우에는 매우 유용하지만, 복잡해지면 직접 JPQL 쿼리를 작성하는 것이 좋다.
쿼리를 직접 실행하려면 @Query 애노테이션을 사용하면 된다.
메서드 이름으로 쿼리를 실행할 때는 파라미터를 순서대로 입력하면 되지만, 쿼리를 직접 실행할 때는 파라미터를 명시적으로 바인딩 해야 한다.
파라미터 바인딩은 @Param("itemName") 애노테이션을 사용하고, 애노테이션의 값에 파라미터 이름을 주면 된다.
ItemService 는 ItemRepository 에 의존하기 때문에 ItemService 에서 SpringDataJpaItemRepository 를 그대로 사용할 수 없다.
물론 ItemService 가 SpringDataJpaItemRepository 를 직접 사용하도록 코드를 고치면 되겠지만, 우리는 ItemService 코드의 변경 없이 ItemService 가 ItemRepository 에 대한 의존을 유지하면서 DI 를 통해 구현 기술을 변경하고 싶다.
클래스 의존 관계
JpaItemRepositoryV2 는 ItemRepository 를 구현한다. 그리고 SpringDataJpaItemRepository 를 사용한다.
이렇게 중간에서 JpaItemRepository 가 어댑터 역할을 해준 덕분에 ItemService 가 사용하는 ItemRepository 인터페이스를 그대로 유지할 수 있고, 클라이언트인 ItemService 의 코드를 변경하지 않아도 되는 장점이 있다.
save()
repository.save(item)
스프링 데이터 JPA 가 제공하는 save() 를 호출한다.
update()
스프링 데이터 JPA 가 제공하는 findById() 메서드를 사용해서 엔티티를 찾는다. 그리고 데이터를 수정한다.
이후 트랜잭션이 커밋될 때 변경 내용이 데이터베이스에 반영된다.
findById()
repository.findById(itemId)
스프링 데이터 JPA 가 제공하는 findById() 메서드를 사용해서 엔티티를 찾는다.
findAll()
데이터를 조건에 따라 4가지로 분류해서 검색한다.
모든 데이터 조회
이름 조회
가격 조회
이름 + 가격 조회
모든 조건이 부합할 때는 findByItemNameLikeAndPriceLessThanEqual() 를 사용해도 되고, repository.findItems() 를 사용해도 된다.
그런데 조건이 2개만 되어도 이름이 너무 길어지는 단점이 있다.
따라서 스프링 데이터 JPA 가 제공하는 메서드 이름으로 쿼리를 자동으로 만들어주는 기능과 @Query 로 직접 쿼리를 작성하는 기능 중에 적절한 선택이 필요하다.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
1️⃣ 스프링 데이터 JPA 소개1 - 등장 이유
EJB 의 지옥을 벗어나기 위해 스프링과 하이버네이트가 등장했다.
스프링은 현재 EJB 컨테이너를 대체하고, 단순함을 가지고 있다.
하이버네이트는 EJB 엔티티빈 기술을 대체하고, JPA 라는 새로운 표준을 정의했다.
관계형 데이터베이스에 mongo DB, redis 등등의 것이 등장하였다.
Spring data 가 가지고 있는 장점
그러나, SPRING DATA 만 아는 것은 자바를 모르고 스프링을 사용하는 것과 같다.
이 기술은 해당 기술을 아는 사람이 편하게 사용하려고 쓰는 것이다.
2️⃣ 스프링 데이터 JPA 소개2 - 기능
예전 순수 JDBC 를 사용하던 시절은, 아래 그림과 같은 계속 동일한 코드를 작성해야했다.

이런 불편함을 SPRING JDBCTEMPLATE 을 사용하면서, 아래와 같이 코드의 길이가 확 줄어들었다.

실제 Spring Data JPA 는 아래의 그림과 같이 실제 아무것도 없다.

Spring Data JPA 는 메서드 이름으로 쿼리를 생성한다.

장점
JPA 를 도입 하기 전
가장 중요한 것은 JPA 자체를 이해하는 것이 중요하다.
3️⃣ 스프링 데이터 JPA 주요 기능
스프링 데이터 JPA 는 JPA 를 편리하게 사용할 수 있도록 도와주는 라이브러리이다.
수많은 편리한 기능을 제공하지만, 가장 대표적인 기능은 다음과 같다.
공통 인터페이스 기능
JpaRepository인터페이스를 통해서 기본적인 CRUD 기능을 제공한다.CrudRepository에서findOne()->findById()로 변경되었다.JpaRepository 사용법
JpaRepository인터페이스를 인터페이스 상속 받고, 제네릭에 관리할<엔티티, 엔티티ID>를 주면 된다.JpaRepository가 제공하는 기본 CRUD 기능을 모두 사용할 수 있다.스프링 데이터 JPA 가 구현 클래스를 대신 생성
JpaRepository인터페이스만 상속받으면 스프링 데이터 JPA 가 프록시 기술을 사용해서 구현 클래스를 만들어준다. 그리고 만든 구현 클래스의 인스턴스를 만들어서 스프링 빈으로 등록한다.쿼리 메서드 기능
스프링 데이터 JPA 는 인터페이스에 메서드만 적어두면, 메서드 이름을 분석해서 쿼리를 자동으로 만들고 실행해주는 기능을 제공한다.
순수 JPA 를 사용하면 직접 JPQL 을 작성하고, 파라미터도 직접 바인딩 해야 한다.
스프링 데이터 JPA 가 제공하는 쿼리 메서드 기능
find...By,read...By,query...By,get....Bycount....By반환타입 :longexists...By반환타입 :boolean,remove....By반환타입 :long`findDistinct,findMemberDistinctByfindFirst3,findFirst,findTop,findTop3JPQL 직접 사용하기
@Query와 함께 JPQL 을 작성하면 된다. 이 때는 메서드 이름으로 실행하는 규칙은 무시된다.4️⃣ 스프링 데이터 JPA 적용1
설정
스프링 데이터 JPA 는
spring-boot-starter-data-jpa라이브러리를 넣어주면 된다.앞에서 JPA 설정하면서 위의 라이브러리를 넣어주었기 때문에 별도의 라이브러리 설정은 하지 않아도 된다.
여기 라이브러리에는 JPA , 하이버네이트, 스프링 데이터 JPA , 스프링 JDBC 관련 기능도 모두 포함되어 있다.
JpaRepository인터페이스를 상속 받으면 기본적인 CRUD 기능을 사용할 수 있다.@Query를 사용해서 직접 쿼리를 실행하면 된다.여기서는 데이터 조건에 따라 4가지로 분류해서 검색한다.
스프링 데이터 JPA 는 동적 쿼리에 약하기 때문에 4가지 상황을 직접 스프링 데이터 JPA 로 구현해보자.
findAll()
코드에선 보이지 않지만
JpaRepository공통 인터페이스가 제공하는 기능이다.모든
Item을 조회한다.select i from Item i과 같은 JPQL 이 실행된다.findByItemNameLike()
이름 조건만 검색했을 때 사용하는 쿼리 메서드이다.
select i from Item i where i.name like ?과 같은 JPQL 이 실행된다.findByPriceLessThanEqual()
가격 조건만 검색했을 때 사용하는 쿼리 메서드이다.
select i from Item i where i.price <= ?과 같은 JPQL 이 실행된다.findByItemNameLikeAndPriceLessThanEqual()
이름과 가격 조건을 검색했을 때 사용하는 쿼리 메서드이다.
select i from Item i where i.itemName like ? and i.price <= ?와 같은 JPQL 이 실행된다.findItems()
메서드 이름으로 쿼리를 실행하는 기능은 다음과 같은 단점이 있다.
메서드 이름으로 쿼리를 실행하는 기능은 간단한 경우에는 매우 유용하지만, 복잡해지면 직접 JPQL 쿼리를 작성하는 것이 좋다.
@Query애노테이션을 사용하면 된다.@Param("itemName")애노테이션을 사용하고, 애노테이션의 값에 파라미터 이름을 주면 된다.5️⃣ 스프링 데이터 JPA 적용2
의존관계와 구조
ItemService는ItemRepository에 의존하기 때문에ItemService에서SpringDataJpaItemRepository를 그대로 사용할 수 없다.ItemService가SpringDataJpaItemRepository를 직접 사용하도록 코드를 고치면 되겠지만, 우리는ItemService코드의 변경 없이ItemService가ItemRepository에 대한 의존을 유지하면서 DI 를 통해 구현 기술을 변경하고 싶다.클래스 의존 관계
JpaItemRepositoryV2는ItemRepository를 구현한다. 그리고SpringDataJpaItemRepository를 사용한다.ItemService->JpaItemRepositoryV2->SpringDataJpaItemRepository (프록시 객체)이렇게 중간에서
JpaItemRepository가 어댑터 역할을 해준 덕분에ItemService가 사용하는ItemRepository인터페이스를 그대로 유지할 수 있고, 클라이언트인ItemService의 코드를 변경하지 않아도 되는 장점이 있다.save()
repository.save(item)스프링 데이터 JPA 가 제공하는
save()를 호출한다.update()
스프링 데이터 JPA 가 제공하는
findById()메서드를 사용해서 엔티티를 찾는다. 그리고 데이터를 수정한다.이후 트랜잭션이 커밋될 때 변경 내용이 데이터베이스에 반영된다.
findById()
repository.findById(itemId)스프링 데이터 JPA 가 제공하는
findById()메서드를 사용해서 엔티티를 찾는다.findAll()
데이터를 조건에 따라 4가지로 분류해서 검색한다.
모든 조건이 부합할 때는
findByItemNameLikeAndPriceLessThanEqual()를 사용해도 되고,repository.findItems()를 사용해도 된다.그런데 조건이 2개만 되어도 이름이 너무 길어지는 단점이 있다.
따라서 스프링 데이터 JPA 가 제공하는 메서드 이름으로 쿼리를 자동으로 만들어주는 기능과
@Query로 직접 쿼리를 작성하는 기능 중에 적절한 선택이 필요하다.SpringDataJpaItemRepository는 스프링 데이터 JPA 가 프록시 기술로 만들어주고 스프링 빈으로도 등록해준다.ItemServiceApplication 변경
예외 변환
스프링 데이터 JPA 도 스프링 예외 추상화를 지원한다. 스프링 데이터 JPA 가 만들어주는 프록시에서 이미 예외 변환을 처리하기 때문에,
@Repository와 관계없이 예외가 변환된다.All reactions