게시판 10 - 추천 기능

JIWOO YUN·2024년 4월 24일
0

게시판만들기

목록 보기
10/21
post-custom-banner
추천 기능을 구현할려면 질문이나 답변을 추천한 사용자가 DB에 저장될 수있도록 속성을 질문 , 답변 엔티티에 추가해야한다.
  • JumpToSpringBoot를 따라가면서 여기서 다대다 맵핑을 쓰는데 이건 좋은 방법은 아닌거같아서 둘 사이에 테이블을 만드는 형식을 생각해서 해볼 예정이다.
    • ManyToMany를 사용하게되면 둘 사이에 새로운 테이블이 생성이 되는데 이건 내가 원해서 만드는 게 아니기 때문에 관리하기가 어려워진다. 그렇기 때문에 직접 연결 테이블만들어서 다대일 , 일대다로 연결해주는게 가장 좋아보인다.
  • 중간에 추천 테이블을 추가해서 SiteUser의 id 값과 board의 id 값을 가진 추천 테이블을 추가해보자.

일단 질문과 유저사이의 추천을 구현해보자.

추천을 누르면 +1 이된다.

  • 같은 사람이 또 누르면 -1 이 된다.

QuestionReco 객체 추가

@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class QuestionReco {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne(fetch = FetchType.LAZY)
    private SiteUser user;

    @ManyToOne(fetch = FetchType.LAZY)
    private Question question;
}
  • 추천 저장용으로 따로 객체를 생성해서 저장할 예정이다.

QuestionRecoController컨트롤러

@Controller
@RequestMapping("/question/vote")
@RequiredArgsConstructor
@Slf4j
public class QuestionRecoController {

    private final QuestionRecoService questionRecoService;
    private final QuestionService questionService;
    private final UserService userService;

    @PreAuthorize("isAuthenticated()")
    @GetMapping("/{id}")
    public String questionVote(Principal principal, @PathVariable("id") Integer id) {
        log.info("추천 시작");

        Question question = questionService.getQuestion(id);
        SiteUser user = userService.getUser(principal.getName());

        QuestionReco Reco = questionRecoService.findReco(user, question);
        if (Reco != null) {
            questionRecoService.delete(Reco);
        } else {
            questionRecoService.insert(user, question);
        }

        log.info("추천 종료");

        return String.format("redirect:/question/detail/%s", id);
    }

}

QuestionRecoService

@RequiredArgsConstructor
@Service
public class QuestionRecoService {

    private final QuestionRecoRepository questionRecoRepository;

    @Transactional
    public void insert(SiteUser user, Question question){
        QuestionReco questionReco = new QuestionReco();
        questionReco.setUser(user);
        questionReco.setQuestion(question);

        questionRecoRepository.save(questionReco);
    }

    @Transactional
    public void delete(QuestionReco questionReco){
        questionRecoRepository.delete(questionReco);
    }

    public QuestionReco findReco(SiteUser user, Question question){
        Optional<QuestionReco> checking = questionRecoRepository.findByUserIdAndQuestionId(user.getId(), question.getId());

        if(checking.isPresent()){
            return checking.get();
        }

        return null;

    }
}
  • 추천을 취소하는 것과 추천하는 걸 분리하지않고 하나로 했다.
    • 생각해보니 추천을 눌렀을 때 이미 누른 경우에는 db에 값이 존재하기 때문에 값이 반환되고 아닌 경우에는 null 값이 반환되어서 추천이 눌리는 형식

답변 추천 기능의 경우에도 질문과 같은 방식으로 진행 하였다.

  • 중복설명이기 때문에 생략
profile
열심히하자
post-custom-banner

0개의 댓글