Blog-v3 (리팩토링), 페이지 네이션

Blog-v3 (리팩토링)
홍윤's avatar
Sep 13, 2024
Blog-v3 (리팩토링), 페이지 네이션
 

1. Board_Test

@Test public void mFindAll1_test() throws JsonProcessingException { // given String title = "제목"; // when Pageable pageable = PageRequest.of(0, 3); Page<Board> boardPG = boardRepository.mfindAll1(title, pageable); // eye ObjectMapper om = new ObjectMapper(); String responseBody = om.writeValueAsString(boardPG); //om.readValue(responseBody, Board.class); System.out.println(responseBody); }
  • 코드설명
💡
이 코드는 JUnit을 사용한 테스트 메소드로, 게시물 조회 기능을 검증하는 테스트입니다. 이 테스트는 제목을 기준으로 게시물을 검색하고 페이지네이션을 적용하여 결과를 얻는 로직을 확인합니다.

1. 메소드 시그니처

@Test public void mFindAll1_test() throws JsonProcessingException {
  • @Test: 이 메소드는 JUnit 테스트 메소드임을 나타냅니다.
  • throws JsonProcessingException: ObjectMapper를 사용해 JSON 변환 작업을 할 때 발생할 수 있는 예외를 처리하기 위해 선언한 부분입니다.

2. given (테스트 준비)

String title = "제목";
  • 테스트에 필요한 입력 값을 설정합니다.
  • 여기서는 title 변수에 "제목"을 설정하여 제목을 기준으로 게시물을 조회하려고 합니다.

3. when (실제 테스트 대상 실행)

Pageable pageable = PageRequest.of(0, 3); Page<Board> boardPG = boardRepository.mfindAll1(title, pageable);
  • Pageable: 페이지네이션을 위한 객체로, PageRequest.of(0, 3)는 0번 페이지(첫 번째 페이지)에서 3개의 게시물을 가져오도록 요청합니다.
    • 첫 번째 인자 0: 페이지 번호.
    • 두 번째 인자 3: 한 페이지에 표시할 게시물의 개수.
  • boardRepository.mfindAll1(title, pageable): boardRepository에서 titlepageable을 기준으로 게시물을 검색하는 메소드입니다. 이 메소드는 제목에 해당하는 게시물 리스트를 페이지 단위로 반환합니다. 반환 타입은 Page<Board>입니다.
    • mfindAll1: 사용자 정의된 쿼리 메소드일 가능성이 높습니다.
    • Page<Board>: 결과는 페이지 객체로 반환되며, 내부에 게시물(Board) 리스트와 페이지네이션 관련 정보를 담고 있습니다.

4. eye (결과 검증을 위한 JSON 변환 및 출력)

ObjectMapper om = new ObjectMapper(); String responseBody = om.writeValueAsString(boardPG); System.out.println(responseBody);
  • ObjectMapper: jackson-databind 라이브러리의 클래스이며, 자바 객체를 JSON 형식으로 변환하거나, 그 반대로 변환할 때 사용됩니다.
    • om.writeValueAsString(boardPG): boardPG 객체를 JSON 문자열로 변환합니다.
    • responseBody: JSON으로 변환된 결과가 문자열로 저장됩니다.
  • System.out.println(responseBody): 변환된 JSON 문자열을 콘솔에 출력합니다. 이를 통해 결과가 제대로 나오는지 확인할 수 있습니다.

주석 처리된 코드

// om.readValue(responseBody, Board.class);
  • 이 주석은 JSON 문자열을 다시 자바 객체로 변환하는 코드입니다.
    • om.readValue(responseBody, Board.class)는 JSON 문자열을 Board 객체로 역직렬화(deserialize)합니다. 테스트에서는 필요 없는 부분이라 주석 처리한 것 같습니다.

전체적인 흐름

  1. "제목"이라는 제목을 가진 게시물을 검색하고, 첫 번째 페이지에서 3개의 게시물을 요청합니다.
  1. 결과로 반환된 게시물 리스트 및 페이지 정보를 JSON 형식으로 변환하여 출력합니다.
  1. 이 테스트는 데이터베이스에 올바르게 쿼리가 실행되는지, 그리고 페이지네이션이 잘 적용되는지를 검증합니다.

2. 테스트 결과 → JSON viewer로 보기!

{"content":[{"id":5,"title":"제목5","content":"내용5","createdAt":1726102187386}, {"id":4,"title":"제목4","content":"내용4","createdAt":1726102187386}, {"id":3,"title":"제목3","content":"내용3","createdAt":1726102187385}], "pageable":{"pageNumber":0,"pageSize":3,"sort":{"empty":true,"sorted":false,"unsorted":true}, "offset":0,"paged":true,"unpaged":false}, "last":false,"totalElements":5, "totalPages":2,"size":3,"number":0, "sort":{"empty":true,"sorted":false,"unsorted":true}, "first":true,"numberOfElements":3,"empty":false}
notion image
💡
이 JSON 구조는 페이지네이션(pagination)을 처리하는 객체를 나타내고 있습니다. 아래는 각 필드에 대한 설명입니다:
  • content: 배열([]) 형태로 나타나 있으며, 실제 데이터가 들어갈 자리입니다. 여기서는 데이터가 비어 있습니다.
  • pageable: 페이지네이션 관련 정보를 담고 있는 객체입니다.
    • last: false로 설정되어 있어, 현재 페이지가 마지막 페이지가 아님을 의미합니다.
    • totalElements: 총 5개의 요소가 있음을 나타냅니다.
    • totalPages: 총 2개의 페이지로 나누어져 있음을 의미합니다.
    • size: 한 페이지당 3개의 요소를 표시합니다.
    • number: 현재 페이지 번호를 나타내며, 0은 첫 번째 페이지임을 의미합니다.
  • sort: 정렬 정보와 관련된 객체입니다.
    • first: true로 설정되어 있어, 현재 페이지가 첫 번째 페이지임을 나타냅니다.
    • numberOfElements: 현재 페이지에 3개의 요소가 포함되어 있음을 의미합니다.
    • empty: false로 설정되어 있어, 페이지가 비어 있지 않음을 나타냅니다.
이 구조는 서버에서 페이지별 데이터를 처리할 때 사용되는 일반적인 JSON 형태로, 페이지네이션 및 정렬 상태를 설명하고 있습니다.

※ 테스트 오류(ByteBuddy 란)

💡
ByteBuddy는 자바 언어에서 바이트코드 조작을 통해 동적으로 클래스를 생성하거나 수정할 수 있는 라이브러리입니다. 이 라이브러리는 리플렉션(reflection)보다 더 효율적이며, 자바의 바이트코드를 런타임에 직접 조작할 수 있는 강력한 도구입니다.

주요 특징:

  1. 런타임에 클래스 생성 및 수정:
      • ByteBuddy를 사용하면 런타임 시점에 동적으로 새로운 클래스를 생성하거나, 기존 클래스를 수정하여 새로운 메소드나 필드를 추가할 수 있습니다.
      • 예를 들어, 프록시 클래스나 인터셉터 클래스와 같은 구조를 쉽게 구현할 수 있습니다.
  1. 자바 바이트코드 조작:
      • 바이트코드는 자바 소스코드가 컴파일된 후 JVM에서 실행되는 중간 코드입니다. ByteBuddy는 이 바이트코드를 조작하여 특정 기능을 추가하거나 기존 동작을 변경할 수 있습니다.
  1. 높은 성능:
      • 자바 리플렉션은 런타임에 메타 데이터를 사용하여 클래스 및 객체 정보를 읽고 수정할 수 있는 기능을 제공하지만, 성능 면에서 다소 느릴 수 있습니다. ByteBuddy는 바이트코드를 직접 수정하기 때문에 리플렉션에 비해 성능이 뛰어납니다.
  1. 에이전트 및 프레임워크 통합:
      • ByteBuddy는 자바의 에이전트 API와 통합되어 애플리케이션의 동작을 변경하거나 프로파일링, 로깅 등을 구현하는 데 사용할 수 있습니다. 대표적인 예로 스프링의 AOP(Aspect-Oriented Programming)에서 ByteBuddy를 사용할 수 있습니다.
  1. 간단한 API:
      • 복잡한 바이트코드 조작을 쉽게 수행할 수 있는 간단한 API를 제공합니다. 직접 바이트코드를 다루는 것에 비해 훨씬 직관적이고 코드가 간결합니다.

예시 코드:

public class Example { public static void main(String[] args) throws Exception { // ByteBuddy를 사용하여 새로운 클래스를 생성하고 메소드를 추가함 Class<?> dynamicType = new ByteBuddy() .subclass(Object.class) // Object 클래스를 상속하는 새 클래스를 생성 .method(ElementMatchers.named("toString")) // toString 메소드를 오버라이드 .intercept(FixedValue.value("Hello ByteBuddy!")) // toString 메소드는 "Hello ByteBuddy!"를 반환 .make() .load(Example.class.getClassLoader()) .getLoaded(); // 동적으로 생성된 클래스의 인스턴스를 생성하고 toString 호출 System.out.println(dynamicType.newInstance().toString()); // 출력: Hello ByteBuddy! } }

주요 용도:

  1. 프록시 클래스 생성:
      • 클래스의 동작을 가로채기 위해 프록시 클래스를 생성할 수 있습니다.
  1. 런타임에서의 동적 클래스 수정:
      • 런타임에 클래스의 메소드를 추가하거나 기존 메소드의 동작을 수정할 수 있습니다.
  1. 코드 성능 최적화:
      • 리플렉션을 사용할 때보다 더 빠르게 동적으로 클래스를 생성하거나 수정할 수 있습니다.
  1. AOP 구현:
      • 특정 메소드에 대해 사전 또는 사후에 동작을 추가하는 AOP와 같은 기능을 구현할 때 유용합니다.
ByteBuddy는 매우 유연하고, 고급 기능을 제공하여 자바 개발에서 필요한 동적 클래스 생성 및 조작 작업을 손쉽게 수행할 수 있게 해줍니다.
Share article

Uni