Jaeyoung Kim
나의 개발 공부 일지
Jaeyoung Kim
전체 방문자
오늘
어제
  • 분류 전체보기 (77)
    • WIL👨‍🏫 (16)
    • 🤖Algorithm (29)
    • 🖥CS (20)
      • 기술면접대비🔎 (10)
    • ✍️개발로그 (10)

블로그 메뉴

  • 홈
  • 방명록
  • 글쓰기
  • 설정

공지사항

인기 글

태그

  • 데이터자료구조
  • HTTP
  • 회고록
  • 백준2920
  • querydsl
  • sql
  • N-gram parser
  • 트랜잭션
  • til
  • WIL
  • 프로그래머스
  • SQLD
  • 백준
  • Java
  • 항해99
  • API
  • 개발로그
  • rest
  • 자바
  • transaction

최근 댓글

최근 글

티스토리

250x250
hELLO · Designed By 정상우.
Jaeyoung Kim

나의 개발 공부 일지

20220726_개발로그_ResponseDto 활용하여 특정 값만 조회하기
✍️개발로그

20220726_개발로그_ResponseDto 활용하여 특정 값만 조회하기

2022. 7. 26. 17:03
728x90

ResponseDto 활용하여 특정 값만 조회하기

스파르타코딩 측에서 제공된 Spring Boot 입문 강의를 따라가며 구현한 GET API는 

기존에 POST했던 API의 모든 값을 가져오는 API였다.

즉 기존에 게시하였던 모든 게시글의 모든 값들을 가져오게 구현되어있었다. 심지어 password까지도.

기존코드

Entity Class

package com.sparta.week03.domain;

import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@NoArgsConstructor 
@Getter
@Entity
public class Post extends Timestamped {

    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private Long id;

    @Column(nullable = false)
    private String username;

    @Column(nullable = false)
    private String contents;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private long password;

    public Post(String username, String contents, String title, long password) {
        this.username = username;
        this.contents = contents;
        this.title = title;
        this.password = password;

    }

    public Post(PostRequestDto requestDto) {
        this.username = requestDto.getUsername();
        this.contents = requestDto.getContents();
        this.title = requestDto.getTitle();
        this.password = requestDto.getPassword();
    }

    public void update(PostRequestDto requestDto){
        this.username = requestDto.getUsername();
        this.contents = requestDto.getContents();
        this.title = requestDto.getTitle();
        this.password = requestDto.getPassword();
    }
}

Controller

@GetMapping("/api/posts")
public List<Post> readAllPost(){
return postRepository.findAllByOrderByModifiedAtDesc();
}

Repository

package com.sparta.week03.domain;

import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface PostRepository extends JpaRepository<Post, Long> {
	List<Post> findAllByOrderByModifiedAtDesc();
}

 

하지만 과제에서 요구하는 내용은 제목, 작성자명, 작성날짜의 값만 작성 날짜 기준 내림차순으로 출력하는 것이었다.

 

아직 내 수준에 위 기능을 한 번에 구현하는 것은 무리가 있다고 판단되어 우선은 작성한 id n 게시글의 일부 값만

출력시키는 것 부터 구현해보기로 하였다.

 

우선 Controller에 집중하였다.

기존의 Controller에서 게시글을 가져오는 메서드인 readAllPost의 경우 return하는 값이 List<Post>로 설정되어 있었기에

Domain Class의 모든 배열들을 가져올 것이 아니기에, 이 부분부터 수정해줘야된다고 판단하였고 

이를 위한 방법으로 responseDto를 생성하고자 하였다.

 

responseDto

package com.sparta.week03.domain;

public class PostResponseDto{

    private String title;
    private String username;
}

수정 날짜 기준 내림차순으로 정렬하는 부분은 이미 강의를 따라 작성하였던 repository 내에서도 구현되었었기에

Repository 단에서도 이 responseDto를 통하여 걸러진 값들을 바탕으로 다시 한 번 정렬해줄 수 있도록 코드를 수정하였다.

 

Repository (1차수정)

package com.sparta.week03.domain;

import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface PostRepository extends JpaRepository<Post, Long> {
        PostResponseDto findAllByOrderByModifiedAtDesc();
}

 

 

Controller에서도 return 값을 기존의 Domain Class의 배열이 아닌 방금 전 작성한 responseDto를 통해 걸러진 값으로 변경하였다.

 

Controller(1차수정)

    @GetMapping("/api/posts")
    public PostResponseDto readAllPost() {
        return postRepository.findAllByOrderByModifiedAtDesc();
    }

 

POST 결과

 

 

GET 결과

생각과는 달리 바로 문제가 발생하였다.

GET으로 값을 받아오지 못하는 것이었다.

 

처음에는 방법 자체가 잘못된거라 생각하여 방법도 바꿔보기도하고 그러다 다시 지금의 방법으로 돌아오기도하고

몇 시간동안 헤매였다.

그렇게 구글링을 수십차례 반복하던 와중, responseDto 단에서 공통적으로 발견되는 어노테이션이 있었고

이를 반영하여 responseDto를 수정 해보았다.

 

responseDto(1차수정)

package com.sparta.week03.domain;

import lombok.AllArgsConstructor;
import lombok.Data;

@AllArgsConstructor
@Data
public class PostResponseDto extends Timestamped{

    private String title;
    private String username;
}

@AllArgsConstructor 그리고 @Data 어노테이션을 추가한 것이다.

 

GET 결과2

너무나 다행히도 특정값만을 출력하는데 성공하였다! 몇 시간 동안 헤맨 후 나온 성과였기에 눈물나게 기뻤다.

그렇담 이를 가능토록 만들어준 위 두 개의 어노테이션은 무엇일까?

잊기 전에 반드시 기록해둬야한다고 생각하였다.

          @AllArgsConstructor - 클래스에 존재하는 모든 필드에 대한 생성자를 자동으로 생성해준다

          @Data - @Getter,@Setter,@RequiredArgsConstructor,@ToString,@EqualsAndHashCode을 한꺼번에 설정

아직 각 생성자들의 차이를 명확하게 구분하지는 못한다. 공부, 계속 공부...📝

 

 

자, 그럼 값을 따로 떼오는 것도 가능해졌으니 이제 작성시간도 포함시켜 POST할 수 있도록 해야한다.

다행히 기존 과제를 진행하며 Timestamped Class를 생성하여 작성 시간 및 수정 시간을 자동으로 받아오게끔 해두었다.

 

Timestamped

package com.sparta.week03.domain;

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@MappedSuperclass
                  
@EntityListeners(AuditingEntityListener.class) 
public abstract class Timestamped {

    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime modifiedAt;
}

 

POST 결과2

이미 Entity Class에 Timestamped Class는 상속되어있고, 분명 H2에 찍어보았을 때는

자동으로 Column에 찍혀나오는 것 같았는데 이번에는 어째서인지 값을 전혀 받아오지 못하고 있었다.

 

이를 해결하기 위해서 또 얼마간의 구글링이 진행되었고, Entity Class에서의 선언이

추가로 이뤄져야 된다는 걸 알게되었다.

//Entity Class 내부에 추가

    @CreatedDate
    private LocalDateTime createdDate;

 

 

POST 결과3

 

발전은 있었으나 여전히 작성시간을 받아오지 못하였다.

몇 차례 구글링을 지속한 결과 추가 어노테이션이 필요하는 것을 알게되었다.

 

Entity Class 그리고 Application 모두에 추가

@EnableJpaAuditing
                             해당 어노테이션이 작성되어야 비로소 Jpa - Timestamped와의 연결이 가능해진다.

 

POST 결과4

이렇게 하고나니 비로소 POST 결과에도 작성날짜가 제대로 출력되어 나왔다.

이제 남은 것은 GET에서도 작성시간을 받아오는 것.

 

나는 앞서 ResponseDto를 통해 GET을 통해 출력되는 데이터를 추려놓았기에 이 부분만을 수정할 필요가 있었다.

 

responseDto(2차수정)

package com.sparta.week03.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import java.time.LocalDateTime;

@AllArgsConstructor
@Data
public class PostResponseDto extends Timestamped{ //Timestamped를 상속받아오고

    private String title;
    private String username;
    private LocalDateTime createdDate; //이 부분 추가
}

 

GET 결과3

드디어 원했던 목표했던 기능들을 모두 구현하였다.

그렇게 생각하지만 한 가지 큰 부분을 놓치고 있었다.

 

내가 작성한 Controller에서의 게시글 목록 조회 GET API 및 Repository는 게시글 배열을 가져오는 것이 아니라

게시글이 1개일 경우에만 띄워주는 API였다.

단일 게시글 조회 기능을 추가하기 위하여 API 테스트를 해보던 중, 게시글을 2개이상 작성 한 후 GET 요청을 하니

바로 오류가 출력되었다.

처음부터 새로운 방법으로 코드를 수정해야하나 고민하던 중 기존 코드와 내가 작성한 코드를 유심히 보고

몇 차례 코딩을 해보니 생각보다 간단하게 문제가 해결되었다.

내가 작성한 코드를 활용하여, 배열로만 받고 출력하면 되는 것이었다.

 

Controller(2차수정)

    @GetMapping("/api/posts")
    public List<PostResponseDto> readAllPost() {
        return postRepository.findAllByOrderByModifiedAtDesc();
    }

Repository(2차수정)

package com.sparta.week03.domain;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface PostRepository extends JpaRepository<Post, Long> {
        List<PostResponseDto> findAllByOrderByModifiedAtDesc();
}

 

GET 결과4

 

겨우 과제에서 요구한 7가지 기능들중 하나이지만 배운 부분이 정말 많았고, 내가 모르는 부분들을 너무나도 많이

발견할 수 있었다.

그리고 무엇보다 문제 해결 방법이 내가 완전히 몰랐던 코드를 추가하는 것이 아닌, 기존 코드에서 수정, 발전시키면

되는 부분이 많았다. 그렇기에 더욱 많이 배울 수 있었다.

 

조금 더 분발하자

728x90

'✍️개발로그' 카테고리의 다른 글

220830_실전프로젝트 8일차(feat.Item 수정부분 트러블슈팅🚀)  (0) 2022.09.03
220829_실전프로젝트 4일차  (0) 2022.08.29
20220823_클론코딩(항해인사이드) 5일차  (0) 2022.08.23
20220820_클론코딩(항해인사이드) 2일차  (0) 2022.08.20
20220726_개발로그(2)_특정게시글 조회(feat.Repository Method)  (0) 2022.07.26
    '✍️개발로그' 카테고리의 다른 글
    • 220829_실전프로젝트 4일차
    • 20220823_클론코딩(항해인사이드) 5일차
    • 20220820_클론코딩(항해인사이드) 2일차
    • 20220726_개발로그(2)_특정게시글 조회(feat.Repository Method)
    Jaeyoung Kim
    Jaeyoung Kim
    보다 안정적인 코드 구현을 꿈꾸는 백엔드 개발자 지망생

    티스토리툴바