본문 바로가기

개발 일지

[TIL]이노베이션 캠프 66일차

1. 개발 진행 상황

기존에 구현한 Post 평가하기, 그리고 그 평가 점수 평균값 저장하기 코드 리팩토링

 

현재 코드

// Controller
// 코스(게시글) 평가 점수 주기 
    @PostMapping( "/api/course/score/{courseId}")
    public ResponseEntity<String> createScore(@PathVariable Long courseId,
                                              @RequestBody ScoreRequestDto requestDto,
                                              @AuthenticationPrincipal UserDetailsImpl userDetails) throws IOException{
        scoreService.scoreCreate(courseId, requestDto, userDetails.getMember());
        return new ResponseEntity<>("평가 성공", HttpStatus.OK);
    }


// Service
    @Transactional
    public void scoreCreate(Long courseId, ScoreRequestDto scoreRequestDto, Member member) throws IOException {
        Post post = postRepository.findById(courseId).orElseThrow(
                () -> new BusinessException("존재하지 않는 게시글 id 입니다.", ErrorCode.POST_NOT_EXIST)
        );

        scoreRepository.save(new Score(post, scoreRequestDto, member));

        post.createScore(scoreRequestDto);
        postRepository.save(post);
    }
    
// Post
// 코스(게시글) 평가 점수 주기 post에 평균 점수 계산해서 들어감
    @ColumnDefault("0")
    private int num;
    @ColumnDefault("0")
    private int score;
    @ColumnDefault("0")
    private double avgScore;
    
    public void createScore(ScoreRequestDto requestDto) {
        this.score += requestDto.getScore();
        this.num += 1;
        this.avgScore = (score/num);
    }

 

❗️문제점 1. member가 post에 score를 주면 그 점수가 중복으로 쌓임

👉🏻 member와 post를 식별하여 중복 데이터가 쌓이지 않도록 변경 필요 -> 평균 점수에도 영향을 미침

👉🏻 점수 생성과 수정 기능의 모호함

 

✅ 해결

member와 post를 가지고 score 데이터 존재 여부 확인 -> 있으면 기존 데이터 삭제하고 새로운 score저장 OR 없으면 score저장

 

 

❗️문제점 2. 직접 계산하는 알고리즘을 사용해서 Post의 평균값을 구하고 있음, 계산을 하기 필요한 필요없는 컬럼 num, socre 발생

 

✅ 해결

@Query를 사용하여 avg를 구하는 코드로 변경

 

// Service
    @Transactional
    public void scoreCreate(Long courseId, ScoreRequestDto scoreRequestDto, Member member) throws IOException {
        Post post = postRepository.findById(courseId).orElseThrow(
                () -> new BusinessException("존재하지 않는 게시글 id 입니다.", ErrorCode.POST_NOT_EXIST)
        );
		
        // post와 member를 조회하여 데이터 중복 저장 해결 
        if (scoreRepository.findScoreByPostAndMember(post, member).isPresent()) {
            scoreRepository.deleteByPostAndMember(post, member);
        }

        scoreRepository.save(new Score(post, scoreRequestDto, member));

        double avgScore = scoreRepository.findAvgScore(courseId);

        post.addAvgScore(avgScore);
        postRepository.save(post);        
    }
    
    
// Repository
public interface ScoreRepository extends JpaRepository<Score, Long> {

    // 평균 Score 구하기
    @Query(value = "SELECT AVG(s.score) FROM Score s WHERE s.post.id = :CourseId")
    double findAvgScore(Long CourseId);
    
    // 중복 Score 검사
    Optional<Score> findScoreByPostAndMember(Post post, Member member);

    // 중복 Score 삭제
    void deleteByPostAndMember(Post post, Member member);

}

 

2. 개발 중 발생한 이슈와 해결

-

3. 새로 배운 것

-

4. 참고 레퍼런스

-

5. 오늘 한 일 / 회고

처음에 어떻게 구현해야하지? 고민했었고 여러가지 방법이 있었지만 내가 할 수 있는 방법으로 구현을 했었는데 역시나 코드가 별로인걸 스스로 느꼈다.

스프링부트를 이용해서 개발을 하는건 편리성을 최대한 이용해서 코드를 만들어라!!! 이런느낌인데 아는게 없어서 원시적으로 코드를 쓰고 있다는걸 엄청나게 느끼고 있다...그 원시적인것마저 잘 몰라서 어려워하고있기도하고...ㅠㅠ

 

계속 자바랑 스프링이랑 공부하면서 조금은 더 나은 코드로 바꿀 수 있지 않을까해서 코드를 수정해봤다.

놀라운건 데이터가 중복으로 쌓이고 있는 문제점을 인지를 못하고 있었다는것이다.

난 그냥 리팩토링 느낌으로 해본거였는데, 아예 문제점이 있는 코드였던 것...ㅎ

공부해가면서 계속 내가 만든 코드를 수정해야겠다.

 

6. TO-DO LIST

찜하기 기능도 원시적으로 더해서? 최종 찜하기 수를 나타냈었는데... 이것도 수정해야겠다.