Books/도메인 주도 개발 시작하기
Chapter5. 스프링 데이터 JPA를 이용한 조회 기능
YoonJong
2024. 4. 8. 15:28
728x90
- CQRS : 명령 모델과 조회 모델을 분리하는 패턴
- 명령 모델 : 상태를 변경하는 기능 구현 ex) 회원 가입, 주문 취소
- 조회 모델 : 데이터를 보여주는 기능 ex) 주문 목록, 주문 상세, 회원 상태
- 스프링 데이터 JPA 간단 예제
// Entity 클래스 생성
@Entity
@Getter
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String author;
}
// Repository 인터페이스 생성
public interface BookRepository extends JpaRepository<Book, Long> {
}
// Service 클래스 생성
@Service
public class BookService {
private final BookRepository bookRepository;
@Autowired
public BookService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
public List<Book> findAllBooks() {
return bookRepository.findAll();
}
public Optional<Book> findBookById(Long id) {
return bookRepository.findById(id);
}
public Book saveBook(Book book) {
return bookRepository.save(book);
}
public void deleteBook(Long id) {
bookRepository.deleteById(id);
}
}
BookRepository 인터페이스에서 다양한 메서드를 작성할 수 있다.
public interface BookRepository extends JpaRepository<Book, Long> {
List<Book> findByAuthor(String author);
// JPQL
@Query("SELECT b FROM Book b WHERE b.title LIKE %:keyword%")
List<Book> findByTitleContaining(@Param("keyword") String keyword);
// Native Query
@Query(value = "SELECT * FROM books WHERE author = :author", nativeQuery = true)
List<Book> findByAuthorWithNativeQuery(@Param("author") String author);
// 페이징(Paging) 처리
// 제목에 특정 단어가 포함된 책을 검색하고 페이징 처리
@Query("SELECT b FROM Book b WHERE b.title LIKE %:keyword%")
Page<Book> findByTitleContaining(@Param("keyword") String keyword, Pageable pageable);
}
// Controller ( 페이징 처리 사용 )
@GetMapping("/books")
public Page<Book> getBooksByTitleContaining(
@RequestParam String keyword,
@RequestParam(defaultValue = "0") int page, // 0 (첫번째 페이지)
@RequestParam(defaultValue = "10") int size) { // 10개 가져온다.
return bookRepository.findByTitleContaining(keyword, PageRequest.of(page, size));
}
- 동적쿼리 → Queydsl 을 사용하자!
public PageImpl<CouponMasterAdminResDto> findAllCouponMasterByDateOrCouponName(
Pageable pageable, String searchStartDate, String searchEndDate, String selectSearchCondition, String searchCondition,
String selectStatus, String searchMainCategory) {
LocalDateTime startDateTime = DateTimeUtils.parseStartDateTime(searchStartDate);
LocalDateTime endDateTime = DateTimeUtils.parseEndDateTime(searchEndDate);
List<CouponMasterAdminResDto> list = queryFactory
.select(new QCouponMasterAdminResDto(
// 필요한 객체
))
.from(couponMaster)
.where(
couponMaster.createdAt.between(startDateTime, endDateTime),
searchContainsCouponName(selectSearchCondition, searchCondition), // 동적쿼리
searchIsUsableOrIsExposed(selectStatus),
searchFilterByMainCategory(searchMainCategory)
)
.orderBy(couponMaster.createdAt.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
private BooleanExpression searchContainsCouponName(String selectSearchCondition, String searchCondition) {
switch (selectSearchCondition) {
case "couponName":
return couponMaster.couponName.contains(searchCondition);
case "couponMasterUuid":
return couponMaster.masterId.eq(searchCondition);
case "createUser":
return couponMaster.createdUser.contains(searchCondition);
case "modifiedUser":
return couponMaster.modifiedUser.contains(searchCondition);
}
return couponMaster.couponName.contains(searchCondition)
.or(couponMaster.masterId.eq(searchCondition))
.or(couponMaster.createdUser.contains(searchCondition))
.or(couponMaster.modifiedUser.contains(searchCondition));
}
728x90