Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

엘라의 개발 스케치 Note

[TIL] 내일배움캠프 75일차(23.07.28.) - Pageable을 사용하여 페이징 및 정렬 기능 만들기, compareTo(), 버블 정렬(Bubble Sort) 본문

내일배움캠프/TIL

[TIL] 내일배움캠프 75일차(23.07.28.) - Pageable을 사용하여 페이징 및 정렬 기능 만들기, compareTo(), 버블 정렬(Bubble Sort)

엘라랑이 2023. 7. 28. 21:46

To-do

  • 플러스 주차 복습 과제 작성: 게시글 작성 API
  • 스프링 심화 개선 과제 작성: Pageable 을 사용하여 페이징 및 정렬 기능 만들기
  • 알고리즘 스터디
  • AOP 및 어노테이션 적용 공부 -> 스터디 발표 자료 정리

TIL

< Pageable을 사용하여 페이징 및 정렬 기능 만들기 >

1. PageDto 만들기

@RequiredArgsConstructor
@AllArgsConstructor
@Builder
public class PageDto {
	private final Integer currentPage;
	private final Integer size;
	private String sortBy;

	public Pageable toPageable() {
		if (Objects.isNull(sortBy)) {
			return PageRequest.of(currentPage - 1, size);
		} else {
			return PageRequest.of(currentPage - 1, size, Sort.by(sortBy).descending());
		}
	}

	public Pageable toPageable(String sortBy) {
		return PageRequest.of(currentPage - 1, size, Sort.by(sortBy).descending());
	}
}

2. Controller 코드 변경 - RequestParam에서 값이 입력되지 않았을 때 기본 값 설정하기

  • ? 페이징을 진행하는데 param에 page와 size를 입력하지 않았을 때 기본 값을 설정하는 법을 몰랐음
  • ! 구글링하여 defaultValue를 설정하면 되는 것을 알게 됨
  • PostController
// 전체 게시글 목록 조회
    @GetMapping("/posts")
    public ResponseEntity<ApiResponseDto> getPosts(
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "size", defaultValue = "5") Integer size) {
        PageDto pageDto = PageDto.builder().currentPage(page).size(size).build();
        return ResponseEntity.ok().body(postServiceImpl.getPosts(pageDto));
    }
// 키워드 검색으로 게시글 조회
    @GetMapping("/posts/search")
    public ResponseEntity<ApiResponseDto> searchPostsByKeyword(
            @RequestParam(value = "keyword", defaultValue = "") String keyword,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "size", defaultValue = "5") Integer size) {
        if (keyword.equals("")) {
            throw new IllegalArgumentException("키워드를 입력해주세요.");
        }
        PageDto pageDto = PageDto.builder().currentPage(page).size(size).build();
        return ResponseEntity.ok().body(postServiceImpl.searchPostsByKeyword(keyword, pageDto));
    }

3. PostService 및 PostServiceImpl 코드 수정

  • PostService
/**
 * 전체 게시글 및 댓글 목록 조회
 * @return 전체 게시글 및 댓글 목록
 */
@Transactional(readOnly = true)
PostListResponseDto getPosts(PageDto pageDto);
/**
 * 키워드 검색으로 게시글 조회
 * @param keyword 찾고자 하는 키워드
 * @return 제목이나 내용에 keyword 가 들어간 게시글 목록
 */
PostListResponseDto searchPostsByKeyword(String keyword, PageDto pageDto);
  • PostServiceImpl
// 전체 게시글 및 댓글 목록 조회
    @Override
    @Transactional(readOnly = true)
    public PostListResponseDto getPosts(PageDto pageDto) {
        List<PostResponseDto> postResponseDtoList = postRepository.findAllByOrderByCreatedAtDesc(pageDto.toPageable()).stream()
                .map(PostResponseDto::new)
                .collect(Collectors.toList());

        return new PostListResponseDto(postResponseDtoList);
    }
// 키워드 검색으로 게시글 조회
    @Override
    @Transactional(readOnly = true)
    public PostListResponseDto searchPostsByKeyword(String keyword, PageDto pageDto) {
        // PostSearchCond 객체를 생성하고 키워드를 설정
        PostSearchCond searchCond = new PostSearchCond();
        searchCond.setKeyword(keyword);

        // PostRepositoryQuery 빈의 search 메서드를 호출하여 검색 결과를 받아옴
        Page<Post> searchedPosts = postRepositoryQueryImpl.search(searchCond, pageDto.toPageable());

        // 검색 결과를 PostResponseDto 리스트로 변환하여 반환
        List<PostResponseDto> postResponseDtoList = searchedPosts.stream()
                .map(PostResponseDto::new)
                .collect(Collectors.toList());

        return new PostListResponseDto(postResponseDtoList);
    }

4. PostRepository, PostRepositoryQuery, PostRepositoryQueryImpl 코드 수정

  • PostRepository
@RepositoryDefinition(domainClass = Post.class, idClass = Long.class)
public interface PostRepository extends JpaRepository<Post, Long>, PostRepositoryQuery {
	List<Post> findAllByOrderByCreatedAtDesc(Pageable pageable);
}
  • PostRepositoryQuery
public interface PostRepositoryQuery {
	Page<Post> search(PostSearchCond cond, Pageable pageable);
}
  • PostRepositoryQueryImpl
@Component
@RequiredArgsConstructor
public class PostRepositoryQueryImpl implements PostRepositoryQuery {

	private final JPAQueryFactory jpaQueryFactory;

	@Override
	public Page<Post> search(PostSearchCond cond, Pageable pageable) {
		QPost post = QPost.post;

		// 제목 또는 내용 중에서 키워드를 포함하는 게시글을 검색 (OR 연산)
		BooleanExpression titleContainsKeyword = post.title.contains(cond.getKeyword());
		BooleanExpression contentContainsKeyword = post.content.contains(cond.getKeyword());

		var query = jpaQueryFactory.select(post)
				.from(post)
				.where(titleContainsKeyword.or(contentContainsKeyword))
				.offset(pageable.getOffset())
				.limit(pageable.getPageSize())
				.orderBy(post.createdAt.desc()); // 작성일자 내림차순 정렬

		var posts = query.fetch();

		if (posts.isEmpty()) {
			throw new NotFoundException("해당 페이지는 존재하지 않습니다.");
		}

		long totalSize = jpaQueryFactory.select(Wildcard.count)
				.from(post)
				.where(
						titleContainsKeyword.or(contentContainsKeyword)
				).fetch().get(0);

		return PageableExecutionUtils.getPage(posts, pageable, () -> totalSize);
	}
}

< compareTo() >

A.compareTo(B) : A < B 일 때 음수, A = B 일 때 0, A > B 일 때 양수 return
 cf) 문자열의 경우 A가 사전적으로 더 앞에 있는 값일 경우 음수 리턴

< 버블 정렬 (Bubble Sort) >

버블 정렬(Bubble Sort) - 출처 위키디피아

  • 버블 정렬이란?
1. 앞에서부터 현재 원소와 다음 원소를 비교하는 방식
2. 두 개의 원소를 비교해서 현재 원소가 다음 원소보다 크면 자리를 교환한다.
3. 다음 원소로 이동한 후 2~3번을 반복한다.
void bubbleSort(int[] arr) {
    int temp = 0;
	for(int i = 0; i < arr.length - 1; i++) {
		for(int j= 1 ; j < arr.length-i; j++) {
			if(arr[j]<arr[j-1]) {
				temp = arr[j-1];
				arr[j-1] = arr[j];
				arr[j] = temp;
			}
		}
	}
	System.out.println(Arrays.toString(arr));
}

Next...

  • JPA 강의 듣기
  • 플러스 주차 복습 과제, 스프링 심화 개선 과제 작성
  • 알고리즘 스터디 및 공부

 

Comments