스프링 데이터 JPA 주요 기능
- 공통 인터페이스 기능
- JPARepository 인터페이스를 통해서 기본적인 CRUD 기능을 제공
- 공통화 가능한 기능이 거의 모두 포함되어 있음.
- 쿼리 메서드 기능
- 인터페이스에 메서드만 적어두면, 메서드 이름을 분석해서 필요한 JPQL을 만들고 실행해준다. JPQL은 JPA가 SQL로 번역해서 실행한다.
- 규칙
- 조회 : find..By, read..By, query..By, get..By
- ex) findByUsernameAndAgeGreaterThan(String username, int age)
- COUNT: count..By / 반환 타입은 long
- EXIST: exists..By / 반환 타입은 boolean
- 삭제 : delete.. By, remove..By / 반환 타입은 long
- DISTINCT: findDistinct, findMemberDistinctBy
- LIMIT : findFirst3, findFirst, findTop, findTop3
- 조회 : find..By, read..By, query..By, get..By
- 쿼리 메서드 기능 대신에 직접 @Query를 이용해서 JPQL을 사용할 수 있다.
사용법
public interface ItemRepository extends JpaRepository<Member, Long> {
}
JpaRepository를 상속받고, 제네릭에 관여할 <엔티티, 엔티티 ID>를 주면 된다. 이렇게 하면 구현 클래스 없이도 기본 CRUD 기능을 사용할 수 있다.
스프링 데이터 JPA 적용
public interface SpringDataJpaItemRepository extends JpaRepository<Item, Long> {
//아래처럼 조건이 있는 거만 적으면 됨. 조건이 없는건 JpaRepository에 findAll()이 있음.
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 기능을 사용할 수 있다.
- 공통적인 CRUD 기능이 아닌 조건이 있는, 이름으로 검색하거나, 가격 제한을 두고 검색하는 기능은 공통으로 제공하지 않아서 쿼리 메서드 기능을 사용하거나, 직접 @Query를 사용해서 JPQL을 작성하면 된다.
- 스프링 데이터 JPA 역시 동적쿼리에 약하다. 이것은 나중에 배우게되는 Querydsl을 사용하면 좋다.
- findItems의 @Query를 이용한 것처럼 쿼리를 직접 실행할 때는 파라미터를 명시적으로 바인딩해야 한다. 파라미터 바인딩은 @Param("itemName")처럼 애노테이션을 사용하고, 애노테이션의 값에 파라미터 이름을 주면 된다.
ItemService의 코드를 변경하여 바로 SpringDataJpaItemRepository에 의존하도록 할 수 있지만, 코드를 그대로 유지하기 위해서 ItemRepository를 상속받는 JpaRepositoryV2를 만들었다.
@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();
}
}
}
ItemRepository를 상속받게하고, 생성자를 통해 앞에서 만든 SpringJpaDataRepository를 주입시킨다. 그리고 각 함수를 구현한다. JPA를 이용한 것보다 메소드 이름을 그대로 사용해서 훨씬 편리하게 사용할 수 있다.
728x90
'Spring' 카테고리의 다른 글
[Spring DB2] 데이터 접근 기술 - 활용 방안 (0) | 2024.03.26 |
---|---|
[Spring DB2] 데이터 접근 기술 - Querydsl (0) | 2024.03.25 |
[Spring DB2] 데이터 접근 기술 - JPA (0) | 2024.03.19 |
[Spring DB2] 데이터 접근 기술 - MyBatis (0) | 2024.03.18 |
[Spring DB2] 데이터 접근 기술 - 테스트 (3) | 2024.03.17 |