본문 바로가기
Spring Boot Project/Plming

[Plming] 게시판 기능 코드 리뷰 2편 (게시글 CRUD 기능)

by slchoi 2022. 4. 13.
728x90
SMALL

이전 글에서는 entity 패키지와 dto 패키지의 코드들을 리뷰했다. 이번 글에서는 게시글 CRUD 기능 관련 코드들을 리뷰해보려고 한다.

각 기능 별로 Controller -> Service -> Repository -> return 값 순서로 코드를 살펴보면서, 궁금한 점과 리팩터링 할 코드가 있는지 정리해볼 것이다.

게시판 CRUD와 관련된 로직은 Board, BoardRepository, BoardCustomRepository, BoardCustomRepositoryImpl, BoardApiController, BoardService 클래스에서 처리한다.

 1. 게시글 생성

BoardApiController

/**
 * 게시글 생성
 */
@PostMapping
public ResponseEntity<Long> save(@RequestBody final BoardRequestDto post, @CookieValue String token) {

    Long userId = jwtTokenProvider.getUserId(token);
    return ResponseEntity.status(201).body(boardService.save(post, userId));
}
  • POST "/posts" 요청이 들어오면 게시글이 생성된다.
  • request body에 제목, 내용, 카테고리, 진행 기간, 모집 상태, 최대 참여 인원수, tag Id 리스트가 들어오면 이 정보들을 BoardRequestDto에 저장한다.
  • Cookie로 전달되는 token을 가져와 token에서 사용자 Id를 꺼내온다.
  • userId와 BoardRequestDto를 BoardService의 save 메서드의 매개변수로 전달한다.
  • boardService의 save 메서드 실행이 끝나고 반환 값으로 받은 게시글의 id를 상태 코드 body에 넣어주고 201 코드로 응답한다.  

 

BoardService

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

    User user = userRepository.findById(userId).orElseThrow(() -> new CustomException(ErrorCode.BAD_REQUEST));
    Board entity = boardRepository.save(params.toEntity(user));
    List<Long> boardTagIds = params.getTagIds();
    boardTagService.save(boardTagIds, entity);

    return entity.getId();
}
  • userRepository에서 userId를 사용해 사용자 정보를 가져온다. userId가 존재하지 않을 경우 예외를 내보낸다.
  • 매개변수로 받아온 BoardRequestDto를 DB에 저장할 수 있도록 Entity 객체로 변환하고, 변환된 객체를 boardRepository의 save 메서드의 매개변수로 전달해 게시글을 생성한다.
    • save 메서드는 JPA Repository에서 제공해주는 CRUD 메서드. save 메서드의 매개변수로 entity를 전달하면 DB에 entity의 데이터를 저장해준다.
  • 매개 변수로 받아온 params에서 TagId 값을 꺼내오고 boardTagService의 save 메서드의 매개변수로 전달해 board의 태그 값을 저장한다.
  • boardTagService의 save 메서드 실행이 끝나면 새로 생성된 게시글의 id를 반환한다.

 

BoardTagService

/**
 * 게시글 태그 저장
 */
@Transactional
public void save(List<Long> tagIdList, Board entity) {

    tagIdList.stream().map(tagId -> BoardTag.builder()
            .board(entity)
            .tag(tagRepository.getById(tagId))
            .build()).forEach(boardTagRepository::save);
}
  • 매개변수로 tagId 리스트와 Board entity를 받아온다.
  • tagId에 있는 값들을 하나씩 가져와 BoardTag entity를 생성하고 boardTagRepository의 save 메서드를 통해 DB의 post_tag 테이블에 저장한다.

 

✍ 공부해야 할 부분 (JPA)
JPA 기본 개념 및 동작 원리

JPA 역시 기본 개념 공부를 진행해본 적이 없어 JPA의 기본 사용법은 알지만, JPA의 동작 원리와 JPA에서 제공해주는 기능에는 어떤 것들이 있는지에 대해 자세히 알지는 못한다.
김영한 님의 "자바 ORM 표준 JPA 프로그래밍" 책을 보며 JPA 공부를 진행해야겠다.

 

2. 게시글 수정

BoardApiController

/**
 * 게시글 수정
 */
@PatchMapping("/{id}")
public ResponseEntity update(@PathVariable final Long id, @RequestBody final BoardRequestDto post, @CookieValue final String token) {

    CustomException e1 = new CustomException(ErrorCode.NOT_ACCEPTABLE);
    Long userId = jwtTokenProvider.getUserId(token);

    if (boardService.update(id, userId, post).equals("인원 수")) {
        return ResponseEntity.status(e1.getErrorCode().getStatus().value())
                .body(new ErrorResponse(e1.getErrorCode(), "현재 게시글에 참여한 인원 수보다 참여 가능한 인원 수를 더 작게 수정할 수 없습니다."));
    }
    if (boardService.update(id, userId, post).equals("모집 완료")) {
        return ResponseEntity.status(e1.getErrorCode().getStatus().value())
                .body(new ErrorResponse(e1.getErrorCode(), "현재 게시글은 모집 완료된 게시글로 수정이 불가능합니다."));
    }

    return ResponseEntity.status(200).body(boardService.update(id, userId, post));
}
  • PATCH "/posts/{id}"로 요청이 들어오면 게시글을 수정하는 로직을 실행한다.
  • Path에서 boardId 값을 가져오고, Cookie에서 token 값을 가져오고, Body에서 게시글을 수정할 정보를 가져와 BoardRequestDto 객체에 저장한다.
  • 게시글 수정을 위해 BoardService의 update 메서드를 호출하고 게시글 id, 사용자 id, 수정할 정보를 담은 BoardRequestDto를 매개변수로 넣어준다.
    • 게시글 수정이 가능한지를 확인할 수 있도록 BoardService의 update 메서드에서 String을 반환하도록 구현했다.
  • 게시글을 수정할 수 없는 경우는 총 3가지이다.
    1. 게시글을 작성한 사용자가 아닌 경우
    2. 현재 게시글에 참여를 수락한 사용자의 수보다 최대 참여 인원수를 더 작게 수정하려는 경우
      • EX) 현재 게시글 참여 수락 인원이 4명인데 게시글을 수정하면서 최대 참여 인원수를 3명으로 감소시키려는 경우
      • BoardService의 update 메서드에서 "인원수"를 반환
    3. 모집 완료된 게시글을 수정하려는 경우
      • BoardService의 update 메서드에서 "모집 완료"를 반환
  • BoardService의 update의 반환 값을 확인해 수정이 가능한 경우(수정한 게시글 id를 반환한 경우) 200 코드와 response body에 수정한 게시글의 id를 담아 반환하고, update가 불가능한 경우 403 코드(1번 경우) 또는 406 코드(2, 3번 경우)를 반환한다.

 

✍ 공부해야 할 부분 (네트워크? WEB?)
HTTP 상태 코드

응답으로 HTTP 상태 코드를 반환해야 할 때마다 구글링 해서 어떤 상태 코드를 반환해야 하는지 찾아보는 과정을 반복했다. HTTP 상태 코드를 한 번 정리해볼 필요가 있을 것 같다.

 

BoardService

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

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

    if(entity.getUser().getId().equals(userId)) {
        if (entity.getStatus().equals("모집 완료")) {
            return "모집 완료";
        }
        if ((!(params.getParticipantMax() == null)) && (params.getParticipantMax() < countParticipantNum(id))) {
            return "인원 수";
        }

        entity.update(params.getParticipantMax(), params.getTitle(), params.getContent(), params.getCategory(), params.getStatus(), params.getPeriod());
        boardTagRepository.deleteAllByBoardId(id);
        boardTagService.save(params.getTagIds(), entity);

        return entity.getId().toString();
    } else {
        throw new CustomException(ErrorCode.FORBIDDEN);
    }
}
  • 매개변수로 게시글 id, 사용자 id, BoardRequestDto 객체를 받아온다.
  • 게시글 id를 사용해서 DB에서 Board 객체 정보를 가져온다. 만약 게시글 id에 해당하는 객체가 없다면 예외가 발생한다.
  • 게시글 id를 사용해서 가져온 Board 객체에서 사용자 정보를 꺼내고, 매개변수로 받은 userId와 게시글을 작성한 사용자 id가 일치하는지 확인한다.
  • userId와 게시글을 작성한 사용자 id가 서로 일치하는 경우
    • Board 객체에서 status 값을 가져와 "모집 완료"인지 확인하고, "모집 완료"일 경우 "모집 완료"를 반환한다.
    • Board 객체에서 최대 참여 인원수 값을 가져오고, 현재 게시글에서 참여가 수락된 사용자의 수를 계산해서 반환해주는 countParticipantNum 메서드의 값을 비교해서 수정하려는 최대 참여 인원수보다 현재 게시글 참여가 수락된 인원 수가 더 많을 경우 "인원수"를 반환한다.
    • 위의 두 경우에 해당되지 않을 경우에만 Board Entity 내부에 작성한 update 메서드를 통해 게시글 수정이 가능하다.
    • 태그 값이 수정될 경우 기존의 게시글이 포함하고 있던 태그는 전부 삭제한 뒤 변경하고자 하는 태그로 다시 저장한다.
    • 게시글 수정이 완료되면 수정된 게시글의 id를 반환한다.
  • userId와 게시글을 작성한 사용자 id가 서로 일치하지 않는 경우 예외가 발생한다.
🙄 궁금한 점 (JPA)
findById( ) 메서드와 getById( ) 메서드의 차이는?

findById( ) 메서드의 경우 Optional<Board>를 getById( ) 메서드의 경우 Board 객체를 바로 반환한다는 차이는 알고 있지만, 테스트 코드를 작성하면서 findById를 사용해 객체를 가져와 객체가 가지고 있는 값을 꺼내는 경우에는 Transaction 오류가 발생하지 않았지만, getById( ) 메서드를 사용해 바로 Board 객체를 가져온 후 객체가 가지고 있는 값을 꺼내는 경우에는 Transaction 오류가 발생했다.

String title = boardRepository.findById(1L).get().getTitle();	// 오류 발생 X
String title = boardRepository.getById(1L).getTitle();		// 오류 발생 O

 

Transaction의 발생 여부의 차이가 단지 두 메서드의 결괏값의 차이 때문인지 아니면 두 메서드의 동작 과정에서 차이가 있어 발생 여부에도 차이가 있는 것인지 찾아봐야겠다. 
✍ 공부해야 할 부분 (DB, Java)

DB의 트랜잭션과 Java의 Optional에 대해 공부해야겠다.

개발을 진행하면서 @Transactional은 DB에 접근해 데이터를 수정하거나 삭제할 때문 붙이면 된다고 생각했었는데, 이 생각이 틀렸던 것 같다. 트랜잭션이 무엇인지, 언제, 왜 발생하는지를 정확하게 알지 못하니 개발을 진행할 때에도 언제 @Transactional 애노테이션을 붙여줘야 하는지 헷갈렸다. DB에 대한 전체적인 공부가 필요하지만, 그중에서도 트랜잭션에 대해서는 조금 더 깊게 공부해야겠다는 생각이 들었다.
JPARepository의 findById 같은 경우 Optional 객체를 반환한다. Optional 객체에 대해서는 자바의 정석을 공부하면서 한번 다뤄본 적 있지만, 현재 정확히 기억이 나지 않으므로, 복습 겸 Optional 객체에 대해 다시 한번 공부해야겠다.

 

3. 게시글 삭제

BoardApiController

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

    boardService.delete(id, jwtTokenProvider.getUserId(token));

    return ResponseEntity.ok().build();
}
  • DELETE "/posts/{id}"로 요청이 들어오면 게시글 삭제 로직을 수행한다.
  • URI의 path에서 게시글 id를 가져오고, Cookie에서 token 정보를 가져와 사용자 id 정보를 추출한다.
  • 게시글 id와 사용자 id를 BoardService의 delete 메서드의 매개변수로 넣어주고 메서드를 호출한다.
  • 게시글 삭제가 완료되면 상태 코드로 200을 반환한다.
🙄 궁금한 점
일반적으로 DELETE 요청이 들어오면 응답을 어떻게 하는지?

프론트엔드 파트에서 DELETE 요청 시에는 response body가 없어도 될 것 같다고 하셔서 상태 코드만 보내도록 구현했는데, 일반적으로 DELETE 요청이 들어오면 응답으로 무엇을 반환하는지 검색해봐야겠다.

 

BoardService

/**
 * 게시글 삭제
 */
@Transactional
public void delete(final Long id, final Long userId) {

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

    if(entity.getUser().getId().equals(userId)) {
        if(entity.getDeleteYn() == '1') {
            throw new CustomException(ErrorCode.ALREADY_DELETE);
        }
        entity.delete();
        boardTagRepository.deleteAllByBoardId(id);
    }
    else {
        throw new CustomException(ErrorCode.FORBIDDEN);
    }
}
  • 매개 변수로 게시글 id와 사용자 id가 들어온다.
  • 게시글 id를 사용해 해당 id에 해당하는 게시글이 있는지 확인한다. 게시글이 있다면 Board 객체를 반환하고 없다면 예외가 발생한다.
  • 반환받은 Board 객체에서 사용자 id를 가져와 매개변수로 전달받은 사용자 id와 비교한다.
  • Board 객체에서 가져온 사용자 id와 매개변수로 전달받은 사용자의 id가 같은 경우 아래 로직을 수행한다.
    (게시글 작성자와 현재 로그인된 사용자가 같은 사용자인 경우) 
    • Board 객체에서 deleteYn의 값을 가져와 '1' 인지 확인하고, '1'일 경우 예외가 발생한다.
    • deleteYn의 값이 '1'이 아닐 경우 Board entity 객체에 구현해둔 delete 메서드를 호출해 게시글을 삭제한다.
    • 게시글이 삭제될 경우 게시글에 포함되어 있던 태그의 값도 모두 삭제한다.
  • Board 객체에서 가져온 사용자 id와 매개변수로 전달받은 사용자의 id가 다른 경우 예외가 발생한다.
    (게시글 작성자와 현재 로그인된 사용자가 다른 사용자인 경우)

 

4. 사용자 Id 기준 게시글 리스트 조회

BoardApiController

/**
 * 게시글 리스트 조회 - 사용자 ID 기준
 */
@GetMapping("/user")
public UserBoardListResponseDto findAllByUserId(@CookieValue final String token) {

    return boardService.findAllByUserId(jwtTokenProvider.getUserId(token));
}
  • GET "/posts/users"로 요청이 들어오면 사용자 Id 기준 게시글 리스트 조회 로직을 수행한다.
  • Cookie에서 token 값을 가져와 token으로부터 사용자 Id를 추출한다.
  • 사용자 id를 BoardService의 findAllByUserId의 매개변수로 넣어주고 findAllByUserId의 반환 값을 response body에 넣어 반환한다.

 

BoardService

findAllByUserId

/**
 * 사용자 Id 기준 댓글 단 게시글 리스트 + 작성한 게시글 리스트 반환
 */
@Transactional
public UserBoardListResponseDto findAllByUserId(final Long userId) {

    return UserBoardListResponseDto.builder()
            .write(findBoardByUserId(userId))
            .comment(findCommentBoardByUserId(userId))
            .build();
}
  • 매개변수로 들어온 사용자 id 값을 findBoardByUserId의 매개변수로 넣어 이 메서드를 호출하고, 반환 값을 UserBoardListResponseDto Builder의 write 값에 넣어준다.
  • 매개변수로 들어온 사용자 id 값을 findCommentBoardByUserId의 매개변수로 넣어 이 메서드를 호출하고, 반환 값을 UserBoardListResponseDto Builder의 comment 값에 넣어준다.
  • findAllByUserId의 반환 값으로 사용자 id에 해당하는 사용자가 작성한 게시글 리스트와 댓글 단 게시글 리스트 정보를 가진 UserBoardListResponseDto를 반환한다.

findBoardByUserId

/**
 * 게시글 리스트 조회 - (사용자 ID 기준)
 */
private List<BoardListResponseDto> findBoardByUserId(final Long userId) {

    List<Board> list = boardRepository.findAllByUserId(userId);
    return getBoardListResponseFromBoardList(list);
}
  • 매개변수로 사용자 id가 들어오면 BoardRepository의 findAllByUserId 메서드를 호출해 사용자가 작성한 게시글 리스트를 불러온다.
  • findAllByUserId 메서드의 반환 값을 getBoardListResponseFromBoardList의 매개변수로 넣어준 뒤, 이 메서드를 호출하고, 이 메서드의 반환 값을 그대로 반환한다.
BoardRepository의 findAllByUserId
@Override
public List<BoardTag> findAllByBoardId(Long boardId) {
    return jpaQueryFactory.selectFrom(boardTag)
            .where(boardTag.board.id.eq(boardId))
            .fetch();
}

boardTag 테이블에서 boardTag.board의 id 값과 매개변수로 주어진 boardId 값이 일치하는 것만 골라 BoardTag 객체 리스트 형태로 반환

findCommentBoardByUserId

/**
 * 댓글 단 게시글 리스트 조회 - (사용자 Id 기준)
 */
private List<BoardListResponseDto> findCommentBoardByUserId(final Long userId) {

    List<Long> boardId = commentService.findCommentBoardByUserId(userId);
    List<Board> boardList = boardId.stream().map(id -> boardRepository.findById(id).get()).collect(Collectors.toList());

    return getBoardListResponseFromBoardList(boardList);
}
  • 매개변수로 받아온 사용자 id를 CommentService의 findCommentBoardByUserId의 매개변수로 넣어준 뒤, 이 메서드를 호출하고, 반환받은 게시글 Id 리스트를 boadId 변수에 저장한다.
  • boardId에 있는 모든 값에 대해 BoardRepository의 findById의 매개변수에 넣어주어 사용자가 댓글을 단 게시글 정보를 가져와 boardList에 저장한다.
    • findById 메서는 JPA Repository에서 기본적으로 제공해주는 메서드이다.
  • boardList를 getBoardListResponseFromBoardList의 매개변수로 넣어준 뒤, 이 메서드를 호출하고, 이 메서드의 반환 값을 그대로 반환한다.

getBoardListResponseFromBoardList

/**
 * 각 게시글의 태그 이름 조회 후 BoardListResponseDto 반환
 */
public List<BoardListResponseDto> getBoardListResponseFromBoardList(List<Board> list) {

    List<BoardListResponseDto> result = new ArrayList<BoardListResponseDto>();
    for(int i = 0; i < list.size(); i++) {

        Integer participantNum = applicationService.countParticipantNum(list.get(i).getId());
        result.add(new BoardListResponseDto(list.get(i), participantNum, boardTagService.findTagNameByBoardId(list.get(i).getId())));
    }

    return result;
}
  • 매개변수로 Board 객체 리스트가 들어오면 각각의 Board 객체로부터  BoardListResponseDto 객체를 생성하고 리스트로 묶어 반환해주는 메서드
  • 반환 값을 저장할 ArrayList를 먼저 생성해준다.
  • 매개변수로 들어온 각각의 Board 객체에 대해
    • ApplicationService의 countParticipantNum 메서드의 매개변수로 넣어주고, 이 메서드를 호출해 현재 게시글에 참가가 승인된 사용자가 몇 명인지 계산하고 결괏값을 participantNum에 저장한다.
    • BoardTagService의 findTagNameByBoardId 메서드를 호출해 게시글이 가지고 있는 태그 이름 리스트 값을 가져온다.
    • 다음으로 각각의 Board 객체와 조금 전에 가져온 값들을 가지고 새로운 BoardListResponseDto 객체를 생성하고, result 리스트에 넣어준다.
  • result 리스트를 반환하면 이 메서드 로직은 끝난다.

 

CommentService

public List<Long> findCommentBoardByUserId(final Long userId) {

    return commentRepository.findCommentBoardByUserId(userId);
}
  • CommentRepository의 findCommentBoardByUserId를 호출해 Board의 사용자 id와 userId가 일치하는 게시글만 불러와 반환한다.
CommentRepository의 findCommentBoardByUserId
@Override
public List<Long> findCommentBoardByUserId(Long userId) {

    return jpaQueryFactory.select(comment.board.id).from(comment)
            .where(comment.user.id.eq(userId), comment.deleteYn.eq('0'))
            .distinct()
            .orderBy(comment.board.id.desc())
            .fetch();
}

comment 테이블에서 매개변수로 주어진 userId값과 comment.user에서 가져온 사용자 id 값이 일치하는 Comment 객체의 board.id 값을 가져와 중복을 제거하고, board.id를 기준으로 내림차순으로 정렬한 뒤 반환한다.

 

ApplicationService

countParticipantNum

/**
 * 게시글 참여자 수 계산
 */
public Integer countParticipantNum(final Long boardId) {

    return findParticipantUserByBoardId(boardId).size();
}
  • 게시글 id가 매개변수로 들어오면 findParticipantUserByBoardId를 호출해 현재 해당 게시글에 참여가 승인된 사용자들의 정보 리스트를 가져온다.
  • 참여가 승인된 사용자 정보 리스트의 크기를 반환한다.

findParticipantUserByBoardId

/**
 * 게시글 참여자 리스트 조회
 */
public List<User> findParticipantUserByBoardId(final Long boardId) {

    return applicationRepository.findParticipantByBoardId(boardId);
}
  • 매개변수로 게시글 id를 가져와 ApplicationRepository의 findParticipantByBoardId의 매개변수로 넣어주고, 이 메서드를 호출해 게시글에 참여가 승인된 사용자들의 정보 리스트를 가져와 반환한다.
ApplicationRepository의 findParticipantByBoardId
/**
 * 참가자 리스트 조회 - (게시글 ID 기준)
 */
@Override
public List<User> findParticipantByBoardId(Long boardId) {

    return jpaQueryFactory.select(application.user).from(application)
            .where(application.board.id.eq(boardId), application.status.eq("승인"))
            .fetch();
}

application 테이블에서 매개변수로 받아온 boardId 값과 board.id가 일치하고, status의 값이 "승인"인 Application 객체 값 중에서 user 정보만 가져와 리스트화해 반환한다.

 

BoardTagService

/**
 * 게시글 id로 태그 이름 조회
 */
public List<String> findTagNameByBoardId (final Long id) {

    List<BoardTag> boardTagList = boardTagRepository.findAllByBoardId(id);
    List<String> boardTagNameList = boardTagList.stream().map(BoardTag::getTag).map(Tag::getName).collect(Collectors.toList());

    return boardTagNameList;
}
  • BoardTagRepository의 findAllByBoardId를 호출해 현재 게시글의 BoardTag 객체를 가져와 boardTagList에 저장한다.
  • boardTagList의 각 값에 대해 Tag 정보를 가져오고, Tag 정보 중에서도 name 값만 꺼내온다.
  • 모든 태그의 name 값을 꺼내와 리스트화해 반환한다.
BoardTagRepository의 findAllByBoardId
@Override
public List<BoardTag> findAllByBoardId(Long boardId) {
    return jpaQueryFactory.selectFrom(boardTag)
            .where(boardTag.board.id.eq(boardId))
            .fetch();
}

boardTag 테이블에서 board.id의 값과 매개변수로 받아온 boardId의 값이 같은 BoardTag 객체만 가져와 반환한다.

 

공부해야 할 부분 (Quserydsl)
Querydsl에 대한 전반적인 내용

SQL 구문이랑 비슷해서 Querydsl을 사용하는 것에 대해 불편함은 없었는데, 무언가를 조회할 때는 뒤에 fetch( )를 붙여야 하고, DB의 레코드를 변경해야 할 경우에는 execute( )를 붙여야 한다고 한다. 이때 fetch( )와 excecute( ) 가 하는 역할이 무엇인지에 대해 공부해봐야겠다. 

또한, Querydsl에 대해 전혀 공부하지 않은 상태에서 프로젝트에 적용만 한 것이기 때문에 Querydsl의 동작 원리 등에 대한 공부가 필요할 것 같다.

 

5. 게시글 상세 정보 조회

BoardApiController

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

    return boardService.findById(id);
}
  • GET "/posts/{id}" 요청이 들어오면 게시글 상세 정보 조회 로직이 수행된다.
  • URI에서 게시글 id를 가져와 boardService의 findById 메서드의 매개변수로 넣어주고, 이 메서드를 호출한다.
  • findById 메서드가 반환하는 값을 그대로 반환한다.

 

BoardService

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

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

    if (entity.getDeleteYn() == '1') {
        throw new CustomException(ErrorCode.POSTS_NOT_FOUND);
    }

    entity.increaseCount();
    List<String> boardTagName = boardTagService.findTagNameByBoardId(id);

    return new BoardResponseDto(entity, applicationService.countParticipantNum(id), boardTagName);
}
  • 매개변수로 받아온 게시글 id를 BoardRepository의 findById 메서드의 매개변수로 넣어주고, 이 메서드를 호출해 게시글 정보를 받아와 entity 변수에 저장한다.
    • findById 메서드는 JPA Repository에서 기본으로 제공해주는 메서드이다.
    • 만약 게시글이 없다면 예외가 발생한다.
  • entity의 deleteYn 값을 가져와 '1'과 비교했을 때 같다면, 게시글이 삭제된 것이므로 예외를 발생시킨다.
  • deleteYn의 값이 '1'이 아닌 경우, Board Entity에 구현한 increaseCount( ) 메서드를 호출하고, BoardTagService의 findTagNameByBoardId 메서드를 호출해 게시글이 가진 태그의 이름 리스트를 가져온다.
  • BoardResponseDto의 생성자에 entity와 boardTagName, ApplicationService의 coutParticipantNum 메서드를 호출해 계산한 현재 게시글의 참여 승인 인원수를 넣어주어 새로운 BoardResponseDto를 생성해 반환한다.

 

🙄 궁금한 점 (JAVA)
== 연산과 equals( ) 메서드의 차이

==은 객체 주소를 비교하고, equals( ) 메서드는 객체의 값을 비교한다고 알고 있었다. 하지만 여기서 이해가 되지 않는 것이 어떤 객체의 값과 null 값을 비교할 때 equals( ) 메서드를 사용할 경우 원하는 대로 결과가 잘 나오지 않았다.. 또한, char 형의 값을 비교할 때는 equals( ) 메서드를 사용해서 비교할 수 없다.

어느 경우에 == 연산을 사용하고, 어느 경우에 equals( ) 메서드를 사용하는지 정리해봐야겠다.

 

이번 글에서는 게시글 CRUD 코드 리뷰를 진행했다. 다음 글에서는 게시글 신청과 검색 관련 코드 리뷰를 진행할 예정이다.

728x90
LIST

댓글