본문 바로가기
Spring Boot Project/Plming

[Plming] DB 설정 변경 및 게시글 기능 추가

by slchoi 2022. 3. 30.
728x90
SMALL

2022년 03월 29일에 팀 회의 진행 결과 게시글 DB에서 변경 사항이 생겨 DB 설정을 변경하고 회의 내용을 토대로 게시글 구현 코드를 변경하고, 게시글의 조회수 증가와 삭제 기능을 추가할 것이다.

1. DB 컬럼 설정 변경

DB 설정을 변경할 때는 DB 안의 데이터가 하나도 없는 상태여야 한다. 만약 DB 안에 데이터가 들어가 있는 경우 "delete from {table 이름}"을 실행해 DB를 비운 뒤 아래 내용을 실행해야 잘 변경될 것이다.

기존 DB 설정을 확인해보면 아래와 같다.

기존 DB 확인

이 중에서 delete_yn의 enum 값을 ('Y', 'N')이 아니라 true, false로 변경하는 것이 좋을 것 같다는 의견이 나와 이 부분을 수정할 것이다. true인 경우 delete_yn의 enum 값은 1이 되고, false인 경우 delete_yn의 값은 0이 된다.

설정을 변경하고 확인해보면 잘 변경된 것을 확인할 수 있다.

delete_yn 설정 변경
변경 결과 확인

DB 설정을 변경했으므로 Board Entitiy 부분의 코드도 변경해주어야 한다.

기존 Board Enitity의 delete_yn 부분 코드를 아래와 같이 수정한다.

@Column(columnDefinition = "enum")
private char deleteYn = '0';

 

2. 게시글 구현 코드 변경

2.1. Mapping 주소 변경

우선 작성한 REST API 문서에 맞게 기존에 '/board'로 Mapping 되어 있던 URI를 '/posts'로 변경할 것이다. 기존의 BoardApiController에서 클래스 레벨에 매핑된 주소를 '/posts'로 변경해주면 된다.

@RestController
@RequestMapping("/posts")
@RequiredArgsConstructor
public class BoardApiController {

DB 변경 내용과 변경한 매핑 주소가 제대로 돌아가는지 확인하기 위해 Postman에서 게시글 하나를 등록해본다.

게시글 등록하기
DB 확인

 

2.2. 게시글 조회 수 증가, 게시글 삭제 기능 추가

먼저 Entity 클래스에 게시글 조회 수 증가시키는 메서드와 게시글을 삭제하는 메서드를 추가한 후, Service 코드를 변경할 것이다.

기존의 Board 클래스에 아래 메서드를 추가한다.

/**
 * 게시글 조회 수 증가
 */
public void increaseCount() {
    this.viewCnt++;
}

/**
 * 게시글 삭제
 */
public void delete() {
    this.deleteYn = '1';
}

increaseCount()와 delete()는 update()와 마찬가지로, JPA의 영속성 컨텍스트에 의해 Transaction이 종료(Commit) 되는 시점에 자동으로 update 쿼리가 실행된다.

다음으로 BoardService 코드를 더보기 코드처럼 수정한다.

더보기
package plming.board.model;

import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import plming.board.dto.BoardRequestDto;
import plming.board.dto.BoardResponseDto;
import plming.board.entity.Board;
import plming.board.entity.BoardRepository;
import plming.board.exception.CustomException;
import plming.board.exception.ErrorCode;

import java.util.List;
import java.util.stream.Collectors;

import static org.springframework.data.domain.Sort.Direction.*;

@Service
@RequiredArgsConstructor
public class BoardService {

    private final BoardRepository boardRepository;

    /**
     * 게시글 생성
     */
    @Transactional
    public Long save(final BoardRequestDto params) {

        Board entity = boardRepository.save(params.toEntity());
        return entity.getId();
    }

    /**
     * 게시글 수정
     */
    @Transactional
    public Long update(final Long id, final BoardRequestDto params) {

        Board entity = boardRepository.findById(id).orElseThrow(() -> new CustomException(ErrorCode.POSTS_NOT_FOUND));
        entity.update(params.getTitle(), params.getContent(), params.getCategory(), params.getStatus(), params.getPeriod());
        return id;
    }

    /**
     * 게시글 삭제
     */
    @Transactional
    public Long delete(final Long id) {
        
        Board entity = boardRepository.findById(id).orElseThrow(() -> new CustomException(ErrorCode.POSTS_NOT_FOUND));
        entity.delete();
        return id;
    }

    /**
     * 게시글 리스트 조회
     */
    public List<BoardResponseDto> findAll() {

        Sort sort = Sort.by(DESC, "id", "createDate");
        List<Board> list = boardRepository.findAll(sort);
        return list.stream().map(BoardResponseDto::new).collect(Collectors.toList());
    }

    /**
     * 게시글 상세 정보 조회
     */
    @Transactional
    public BoardResponseDto findById(final Long id) {

        Board entity = boardRepository.findById(id).orElseThrow(() -> new CustomException(ErrorCode.POSTS_NOT_FOUND));
        entity.increaseCount();
        return new BoardResponseDto(entity);
    }
}

delete( ) 메서드

  • update( ) 메서드와 유사한 형태의 메서드
  • 조회한 Entity를 수정하느냐, 삭제하느냐의 차이

findById( ) 메서드

  • 게시글의 조회 수를 증가시킨 후에 게시글 정보를 리턴

 

마지막으로 BoardApiController 클래스를 더보기 코드와 같이 수정한다. API Controller에서는 BoardService의 delete( ), findById( ) 메서드와 URI만 매핑해주면 된다.

더보기
package plming.board.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import plming.board.dto.BoardRequestDto;
import plming.board.dto.BoardResponseDto;
import plming.board.model.BoardService;

import java.util.List;

@RestController
@RequestMapping("/posts")
@RequiredArgsConstructor
public class BoardApiController {

    private final BoardService boardService;

    /**
     * 게시글 생성
     */
    @PostMapping
    public Long save(@RequestBody final BoardRequestDto post) {
        
        return boardService.save(post);
    }

    /**
     * 게시글 수정
     */
    @PatchMapping("/{id}")
    public Long save(@PathVariable final Long id, @RequestBody final BoardRequestDto post) {
        
        return boardService.update(id, post);
    }

    /**
     * 게시글 삭제
     */
    @DeleteMapping("/{id}")
    public Long delete(@PathVariable final Long id) {

        return boardService.delete(id);
    }
    
    /**
     * 게시글 리스트 조회
     */
    @GetMapping
    public List<BoardResponseDto> findAll() {
        
        return boardService.findAll();
    }

    /**
     * 게시글 상세정보 조회
     */
    @GetMapping("/{id}")
    public BoardResponseDto findById(@PathVariable final Long id) {
        
        return boardService.findById(id);
    }

}

 

2.3. API 테스트

Postman을 사용해 추가한 기능들이 잘 작동하는지 테스트해볼 것이다.

우선, 게시글 상세정보를 조회하는 findById( ) 메서드를 테스트해보자. URI의 마지막에는 board 테이블의 id 값을 지정해주면 된다.

findById( ) 테스트 결과

응답으로 id에 해당하는 게시글 정보를 반환하는 것과 viewCnt의 값이 1 증가한 것을 확인할 수 있다.

다음으로 게시글 삭제를 처리하는 delete( ) 메서드를 테스트해볼 것이다. Request Method만 DELETE로 변경해주면 된다.

delete( ) 테스트 결과

응답으로 삭제 요청한 게시글의 id를 반환하는 것을 확인할 수 있다.

MySQL Workbench에서 해당 게시글 정보를 조회해보면 delete_yn 컬럼 값이 "1"로 변경되었지만, Postman에서 GET 요청으로 게시글 리스트를 요청하면 게시글 리스트에 삭제된 게시글이 포함되어 있는 것을 볼 수 있다.

GET 메서드로 게시글 리스트를 요청한 결과

이 오류를 해결하기 위해 BoardRepository에 아래 메서드를 추가한다. 삭제되지 않는 데이터만 조회하는 기능을 적용하기 위해 BoardRepository에 deleteYn을 파라미터로 전달받는 메서드를 추가한다.

package plming.board.entity;

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

import java.util.List;

public interface BoardRepository extends JpaRepository<Board, Long> {

    /**
     * 게시글 리스트 조회 - (삭제 여부 기준)
     */
    List<Board> findAllByDeleteYn(final char deleteYn, final Sort sort);
}

그다음으로 BoardService에 아래 메서드를 추가한다. (기존에 정의해둔 findAll( ) 밑에 추가하면 된다.)

/**
 * 게시글 리스트 조회 - (삭제 여부 기준)
 */
public List<BoardResponseDto> findAllByDeleteYn(final char deleteYn) {

    Sort sort = Sort.by(DESC, "id", "createDate");
    List<Board> list = boardRepository.findAllByDeleteYn(deleteYn, sort);
    return list.stream().map(BoardResponseDto::new).collect(Collectors.toList());
}

마지막으로 BoardApiController의 findAll( ) 메서드를 아래와 같이 변경한다. 파라미터로 deleteYn을 전달받고, BoardService의 findAllByDeleteYn을 호출하는 형태로 변경되었다.

/**
 * 게시글 리스트 조회
 */
@GetMapping
public List<BoardResponseDto> findAll(@RequestParam final char deleteYn) {

    return boardService.findAllByDeleteYn(deleteYn);
}

변경한 후 Postman으로 다시 게시글 리스트를 요청할 때에는 query parameter로 deleteYn = '0'를 추가해서 요청해야 한다. 지금은 데이터를 하나만 가지고 있기 때문에 POST 메서드로 데이터를 하나 더 추가한 뒤에 테스트해보자.

게시글 추가

GET 메서드로 게시글 리스트를 요청해보면 삭제된 게시글은 반환되지 않는 것을 확인할 수 있다.

게시글 리스트 요청 결과

게시글을 삭제해도 실제 DB에서 삭제되지는 않기 때문에 DB에서는 삭제된 게시글 정보를 확인할 수 있다.

DB 확인하기

 

728x90
LIST

댓글