-
데이터 접근 기술- 활용BackEnd/Spring DB 2023. 2. 9. 01:00반응형
Querydsl을 사용한 리포지토리는 스프링 데이터 JPA를 사용하지 않았습니다. 이번에는 스프링 데이터 JPA와 Querydsl을 함께 사용하는 구조에 대해 알아보겠습니다.
복잡한 쿼리 분리
ItemRepositoryV2는 기본 CRUD 기능을 제공하는 스프링 데이터 JPA 리포지토리이고, ItemQueryRepositoryV2는 복잡한 쿼리 기능을 제공하는 Querydsl 리포지토리입니다.
package hello.itemservice.repository.v2; import hello.itemservice.domain.Item; import org.springframework.data.jpa.repository.JpaRepository; public interface ItemRepositoryV2 extends JpaRepository<Item, Long> { }
package hello.itemservice.repository.v2; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import hello.itemservice.domain.Item; import hello.itemservice.domain.QItem; import hello.itemservice.repository.ItemSearchCond; import org.springframework.stereotype.Repository; import org.springframework.util.StringUtils; import javax.persistence.EntityManager; import java.util.List; import static hello.itemservice.domain.QItem.*; @Repository public class ItemQueryRepositoryV2 { private final JPAQueryFactory query; public ItemQueryRepositoryV2(EntityManager em) { this.query = new JPAQueryFactory(em); } public List<Item> findAll(ItemSearchCond cond) { return query.select(item) .from(item) .where( likeItemName(cond.getItemName()), maxPrice(cond.getMaxPrice()) ) .fetch(); } private BooleanExpression likeItemName(String itemName) { if (StringUtils.hasText(itemName)) { return item.itemName.like("%" + itemName + "%"); } return null; } private BooleanExpression maxPrice(Integer maxPrice) { if (maxPrice != null) { return item.price.loe(maxPrice); } return null; } }
다음은 두 리포지토리를 사용하는 서비스 코드입니다.
package hello.itemservice.service; import hello.itemservice.domain.Item; import hello.itemservice.repository.ItemSearchCond; import hello.itemservice.repository.ItemUpdateDto; import hello.itemservice.repository.v2.ItemQueryRepositoryV2; import hello.itemservice.repository.v2.ItemRepositoryV2; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; @Service @RequiredArgsConstructor @Transactional public class ItemServiceV2 implements ItemService { private final ItemRepositoryV2 itemRepositoryV2; private final ItemQueryRepositoryV2 itemQueryRepositoryV2; @Override public Item save(Item item) { return itemRepositoryV2.save(item); } @Override public void update(Long itemId, ItemUpdateDto updateParam) { Item findItem = itemRepositoryV2.findById(itemId).orElseThrow(); findItem.setItemName(updateParam.getItemName()); findItem.setPrice(updateParam.getPrice()); findItem.setQuantity(updateParam.getQuantity()); } @Override public Optional<Item> findById(Long id) { return itemRepositoryV2.findById(id); } @Override public List<Item> findItems(ItemSearchCond cond) { return itemQueryRepositoryV2.findAll(cond); } }
다양한 데이터 접근 기술 조합
이번 강의는 실무에서 어떤 데이터 접근 기술이 Best Practice인지 고민이 되어 수강하게 되었습니다. 비즈니스 및 프로젝트 상황에 따라 다르겠지만, 강의에서 추천하는 방향은 JPA, 스프링 데이터 JPA, Querydsl을 기본으로 사용하고, 복잡한 쿼리의 경우 JdbcTemplate나 MyBatis를 함께 사용하는 것입니다.
트랜잭션 매니저
- JPA, 스프링 데이터 JPA, Querydsl: JpaTransactionManager
- JdbcTemplate, MyBatis: DataSourceTransactionManager
JpaTransactionManager는 DataSourceTransactionManager가 제공하는 기능 대부분을 제공합니다. 결과적으로 JpaTransactioinManager를 스프링 빈에 등록하면, JPA, JdbcTemplate, MyBatis 모두를 하나의 트랜잭션으로 묶어서 사용할 수 있습니다.
[참고 정보]
반응형'BackEnd > Spring DB' 카테고리의 다른 글
트랜잭션(Transaction) 옵션 (0) 2023.02.11 트랜잭션(Transaction) 심화 (0) 2023.02.11 데이터 접근 기술- QueryDSL (0) 2023.02.04 데이터 접근 기술- Spring Data JPA (0) 2023.02.04 데이터 접근 기술- JPA (2) 2023.02.04