[12.22] 내일배움캠프[Spring] TIL-37

박상훈·2022년 12월 22일
0

내일배움캠프[TIL]

목록 보기
37/72

[12.22] 내일배움캠프[Spring] TIL-37

1. Spring 숙련과제 완료

진행상황

  • 현재 직급에 따른 권한 분류와 댓글의 작성까지 작업했었다.

Problem 등장

  • 게시글 < -> 댓글 : 나는 댓글의 입장에서 게시글의 고유 BOARD_ID를 가진다면, 요구사항을 만족시킬 수 있기 때문에 양방향 관계설계를 하지 않았었다. 실제로 요구사항을 만족시키는데는 굳이 양방향 연관까지는 필요가 없었다.
  • 하지만 게시글의 입장에서 하나의 게시글이 여러 댓글을 가지고 있는 입장이 될 수 있고, 게시글을 통해 댓글에 접근해야 하는 경우가 생길 수 있었고, 양방향 연관관계로 설정해주었다.
  • 양방향 연관관계로 인해 기존에 코드에 대한 순환 오류가 여기저기서 터지기 시작했다.StackOverFlow

기존 Controller 설계 - Problem

 @GetMapping("/board/list")
    public List<Board> getBoardList(){
        return boardService.getBoardAll();
    }
  • Entity자체를 반환하는 경우를 최소화 해야했다.
  • 현재 Controller@RestController이다. -> View랜더링이 아니고, Json타입으로 반환 값을 보는 프로젝트 였기 때문이다.
  • 그럼 List<Boadr>Json으로 반환해야하는데,이 때 순환참조의 오류가 발생한다.
  • 사실 Entity자체를 반환하지 않았다면 생기지 않았을 것 -> 실제로 StackOverFlow의 오류가 터져도, H2를 들여다 보면 정상적으로 데이터는 들어가있다.

설계 Problem에 따른 해결방안 모색

  • 사실 간단한 해결 방법은 존재했다.
  • @JsonManagedReference , @JsonBackReference 의 어노테이션을 연관관계 주인 엔티티와 아닌 엔티티를 구별하여 넣어준다면 순환참조를 막을 수 있다.
  • 하지만 반환 DTO를 만들어 주는 방법을 선택했고, 많이들 좋다고는 하지만 아직 직접 느껴보지는 못했다.
  • 결론 : DTO를 응답 객체를 감싸 Response해주자!

설계 Problem에 따른 해결(Board Part)

  • Board Entity자체를 지금까지 반환했었기 때문에 Comment와 양방향 연관관계가 형성되자, 당연히 순환 참조의 오류가 발생할 수 밖에 없다.

BoardResponseDto

package com.sparta.spartaboard.dto;

import com.sparta.spartaboard.entity.Board;
import com.sparta.spartaboard.entity.Comment;
import lombok.Getter;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Getter
public class BoardResponseDto {

    private String title;
    private String username;
    private String contents;
    private LocalDateTime createdAt;
    private LocalDateTime modifiedAt;
    private List<CommentResponseDto> commentList = new ArrayList<>();

    public BoardResponseDto(Board board ) {
        this.title = board.getTitle();
        this.username = board.getUsername();
        this.contents = board.getContents();
        this.createdAt = board.getCreatedAt();
        this.modifiedAt = board.getModifiedAt();
                for(Comment comment : board.getComments()){
                    commentList.add(new CommentResponseDto(comment));
                }
    }
}
  • 사실 commentList로 넣는 부분에서 많이 애먹었다.
  • 게시글이 해당 게시글에 따른 댓글을 가지고 있어야하기 때문에 ..!

BoardService 수정

 @Transactional
    public List<BoardResponseDto> getBoardAll(){...}
    
 @Transactional
    public BoardResponseDto createBoard(BoardRequestDTO boardDto, HttpServletRequest request) {...}
    
@Transactional
    public Optional<BoardResponseDto> findBoardById(Long id){...}
    
@Transactional
    public BoardResponseDto update(Long id, BoardRequestDTO boardDto, HttpServletRequest request){...}
  • 그냥 Entity(Boadr)가 아닌 Dto로 감싸서 return하여 순환참조오류를 막았다.

설계 Problem에 따른 해결(Comment Part)

CommentResponseDto

package com.sparta.spartaboard.dto;

import com.sparta.spartaboard.entity.Board;
import com.sparta.spartaboard.entity.Comment;
import com.sparta.spartaboard.entity.User;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class CommentResponseDto {

    private Long id;
    private String contents;

    private LocalDateTime createdAt;

    private LocalDateTime modifiedAt;


    public CommentResponseDto(Comment comment) {
        this.id = comment.getId();
        this.contents = comment.getContents();
        this.createdAt = comment.getCreatedAt();
        this.modifiedAt = comment.getModifiedAt();

    }

}

CommentService 수정 및 추가

@Transactional
    public CommentResponseDto addComments(Long id, CommentRequestDto requestDto, HttpServletRequest request) {...}
    
 @Transactional
    public List<CommentResponseDto> getComments(Long id, HttpServletRequest request) {...}
    
 @Transactional
    public CommentResponseDto update(Long id,CommentRequestDto commentRequestDto, HttpServletRequest request){...}
    
   // Delete 구문은 요구조건에 msg와 StatusCode를 Json으로 반환하라는 조건에 따라 다른 Dto로 감싸서 return 했다.
 @Transactional
	public ResponseMsgStatusCodeDto delete(Long id, HttpServletRequest request){...}

Problem 해결 후 동작 모습





2. Java - CodingTest

Level - 0

핸드폰 번호 암호화

  • 문제 설명
    1.프로그래머스 모바일은 개인정보 보호를 위해 고지서를 보낼 때 고객들의 전화번호의 일부를 가립니다.
  • 입출력 예시
phone_numberreturn
"01033334444""***4444"
"027778888""*8888"
class Solution {
       public String solution(String phone_number) {

        //핸드폰 번호 String phone_number

       String last_four_num = phone_number.substring(phone_number.length()-4);
        StringBuffer phoneSecretNum = new StringBuffer();

        for(int i=0;i<phone_number.length()-4;i++){
            phoneSecretNum.append("*");
        }
        phoneSecretNum.append(last_four_num);
        phoneSecretNum.toString();
        return phoneSecretNum.toString();
       }
}

문자열 다루기 기본

  • 문제 설명
    1.문자열 s의 길이가 4 혹은 6이고, 숫자로만 구성돼있는지 확인해주는 함수, solution을 완성하세요. 예를 들어 s가 "a234"이면 False를 리턴하고 "1234"라면 True를 리턴하면 됩니다.
  • 입출력 예시
sreturn
"a234"false
"1234"true
public boolean solution(String s) {
        //s의 길이가 4 or 6
        // 문자 없냐? == True
        char[] res = s.toCharArray();

        if(s.length()==4 || s.length()==6 ){
            for(char i : res){
                if(i > 'A'){
                    return false;
                }
            }
            return true;
        }
        return false;

    }

x만큼 간격

  • 문제 설명
    1.함수 solution은 정수 x와 자연수 n을 입력 받아, x부터 시작해 x씩 증가하는 숫자를 n개 지니는 리스트를 리턴해야 합니다. 다음 제한 조건을 보고, 조건을 만족하는 함수, solution을 완성해주세요.
  • 입출력 예시
xnanswer
25[2,4,6,8,10]
43[4,8,12]
-42[-4, -8]
class Solution {
       public long[] solution(int x, int n) {

        //정수 x , 자연수 n 입력 받아 , x 부터 시작해 x씩 증가하는 숫자 n개를 리턴
        long acc = x;
        long[] answer = new long[n];
        for(int i=0;i<n;i++){

            answer[i] = acc;
            acc+=x;

        }
        return answer;
    }
}
profile
기록하는 습관

0개의 댓글