[Spring] RestAPI 게시판 API만들기 - 1 (전체 게시판 리스트 출력)

nana·2024년 8월 25일
0

Spring

목록 보기
1/9
post-thumbnail

전체 게시글 목록 조회 요구사항

  • 제목, 작성자명, 작성 내용, 작성 날짜를 조회하기
  • 작성 날짜 기준 내림차순으로 정렬하기

✔️ BOARD_LIST 테이블 구조

CREATE TABLE BOARD_LIST(
	  SEQ_NO	BIGINT NOT NULL PRIMARY KEY auto_increment,
      TITLE	VARCHAR(255),
      CONTENTS TEXT, #TEXT를 사용하면 길이 제한이 사라짐.  
	--	USER_NAME VARCHAR(20) NOT NULL ,
      PASSWORD VARCHAR(15) NOT NULL, 
      USE_YN CHAR(1) NOT NULL,
      REG_ID VARCHAR(20),
	  REG_IP VARCHAR(15),
      REG_DATE DATETIME,
      EDIT_ID VARCHAR(20),
      EDIT_IP VARCHAR(15),
      EDIT_DATE DATETIME
        
);

SEQ_NO를 PK로 설정하고 auto_incrment를 설정했다.

테이블 설계시에 간과하고 있었던 점은 MySQL에는 NVARCHAR 타입이 없다는것이었다.
테이블 설계 후에 팀원들과 얘기하는데 NVARCHAR가 뭐예요? 라고 하길래 당황했던 기억이있다.. ㅎㅎ

추가 요구사항에 댓글기능도 있었지만 댓글에 대한 테이블은 seq_no를 외래키로 하는 테이블을 새로 만들 예정이다.

게시글 삭제 시 use_yn ='N'으로 soft delete를 할 것이고 이 때 edit_id, edit_ip, edit_date컬럼을 사용할 예정이다.

✔️ BOARD_LIST Entity


@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name="BOARD_LIST")
public class BoardList {


    @Id
    @Column(name="seq_no")
    private Integer seqNo;
    
    @Column(name="title", nullable = false)
    private String title;
    
    @Column(name="contents", nullable = false)
    private String contents;

    @Column(name= "password")
    private String password;

    @Column(name= "use_yn")
    private String useYn;
    
    @Column(name="reg_id")
    private String regId;
    
    @Column(name="reg_date")
    private String regDate;

    @Column(name="reg_ip")
    private String regIp;

    @Column(name="edit_id")
    private String editId;

    @Column(name="edit_date")
    private String editDate;

    @Column(name="edit_ip")
    private String editIp;

    public BoardList(String title, String regId, String contents, String regDate)
    {
        this.title = title;
        this.regId = regId;
        this.contents = contents;
        this.regDate = regDate;
    }
}

🌀Data : @Getter, @Setter, @RequiredArgsConstructor, @ToString, @EqualsAndHashCode을 한꺼번에 설정해주는 매우 유용한 어노테이션이다.
정말 끝판왕인듯..!!
🌀NoArgsConstructor : 파라미터가 없는 기본 생성자를 생성
🌀AllArgsConstructor : 모든 필드 값을 파라미터로 받는 생성자를 만들어줌.

✔️ BoardController

@RestController
@RequiredArgsConstructor //BoardService에 대한 멤버 사용
@RequestMapping("/api/boards")
public class BoardController {


    private final BoardService boardService;
 @GetMapping(value = "/posts")
    public ResponseEntity<List<BoardList>> getAllPosts() {
        List<BoardList> posts = boardService.getAllPosts();
        return ResponseEntity.ok(posts);
    }

    @GetMapping(value = "/posts2")
    public ResponseEntity<List<BoardList>> getAllPosts2() {
        List<BoardList> posts = boardService.getAllPosts2();
        return ResponseEntity.ok(posts);
    }

    @GetMapping(value="/posts3")
    public ResponseEntity<List<PostSummaryProjection>> getAllPosts3() {
        List<PostSummaryProjection> posts = boardService.getAllPost3();
        return ResponseEntity.ok(posts);
    }

}

🌀RequiredArgsConstructor : final이나 @NonNull인 필드 값만 파라미터로 받는 생성자를 만들어줌.
🌀RequestMapping : 들어온 요청을 특정 메서드와 매핑하기 위해 사용하는 것

@RequestMapping(value = "/api/board", method = RequestMethod.GET)

어떤 요청으로 받을것인지 method에서 정의할 수 있다.

✔️ BoardController


@Service
public class BoardService {



    private final BoardListRepository boardListRepository;

    public BoardService(BoardListRepository boardListRepository) {
        this.boardListRepository = boardListRepository;
    }

    public List<BoardList> getAllPosts(){
        return boardListRepository.findAll(Sort.by(Sort.Direction.DESC,"regDate"));

    }
    public List<BoardList> getAllPosts2(){
        return boardListRepository.findPostSummaries();
    }

    public List<PostSummaryProjection> getAllPost3(){
        return boardListRepository.findAllBy(Sort.by(Sort.Direction.DESC, "regDate"));
    }
}

처음에 @Autowired 를 사용하여 의존성을 주입하였으나 생성자 주입 방식의 장점을 알게되어 생성자 주입방식으로 변경하였다.

getAllPosts라는 모든 게시글을 리스트로 뿌려주는 매서드를 생성하였는데

  • getAllPosts() : 모든 데이터를 출력한 후 등록일기준으로 내림차순 하는 매서드이다.
  • getAllPosts2() : Native Query Entity에 DTO를 생성하여 @Query 로 select하여 생성하는 방법 그치만 이건 API json 반환 시 원하는 컬럼만 반환해주지는 않았다. 때문에 사용되지 않는 방법이라고 한다.
  • getAllPosts3() : Projection Interface를 이용
    조회하는 테이블이 ROOT테이블 일 경우 전체 컬럼을 조회하는 것이 아닌, 원하는 컬럼만을 뽑아낼 수도 있기에 성능개선측면과 응답성 측면에서 장점이 있다.

✔️ BoardRepository

@Repository
public interface BoardListRepository extends JpaRepository<BoardList, String> {

    //DTO로 select하는 방법
    @Query("SELECT new ~~.entity.BoardList( p.title, p.regId, p.contents, p.regDate) FROM BoardList p ORDER BY p.regDate DESC")
    List<BoardList> findPostSummaries();

    //Projection이용해서 하는 방법
    List<PostSummaryProjection> findAllBy(Sort regDate);
}

@Query에서 약간 헤맸던 부분은 실제 테이블의 컬럼명으로 하는건지 엔티티에 정의된 컬럼명으로 하는건지였다.
엔티티에 정의 된 후에 소스에서 쓰이는 부분은 다 엔티티에 정의된 네이밍을 사용할것!

✔️ PostSummaryProjection

public interface PostSummaryProjection {
    Integer getSeqNo();
    String getTitle();
    String getContents();
    String getRegDate();
    String getRegId();
}

이렇게 사용하면 원하는 컬럼만 뽑아낼 수 있다.

👉🏻결과

postMan으로 GET호출 했을 때 날짜 내림차순, 원하는 컬럼(제목,내용,작성자,작성일자)을 추출할 수 있다.

https://devlog-wjdrbs96.tistory.com/166
https://learngoeson.tistory.com/51

profile
BackEnd Developer, 기록의 힘을 믿습니다.

0개의 댓글