[Java] 게시글 추천/비추천 기능
2021. 5. 14. 11:44

1. board테이블에 추천/비추천 컬럼 추가 (with. jpa)

Board.java

2. boardId와 userId를 가진 테이블 생성 (likeCount)

- 예를 들어, 2번 게시판에 1번 유저가 추천기능을 사용했다면 likeCount테이블에 행이 추가되기에

나중에 2번게시판에서 1번유저가 추천버튼을 눌렀을때 likeCount테이블에 값을 select해서 값이 있다면 추천 안되게끔 하기위함

 

 

3. 추천 / 비추천 버튼 만들기

<button type="button"  class="btn btn-Light" onclick="index.like(${likeCount})"
	style="border: 1px solid black;">👍</button>
<button type="button"  class="btn btn-Light" onclick="index.unlike(${likeCount})"
	style="border: 1px solid black;">👎</button>
            
            
<script src="/js/board.js"></script>

 

 

4. 각 버튼에 id를 가지고 ajax 통신으로 컨트롤러로 전달하기 (이때 게시판의 id도 같이 가져온다.)

	like:function(likeCount){  
		var id = $("#id").text();   
		if(likeCount == undefined){
			$.ajax({ 
				method: "POST",
				url: "/api/boardlike/"+id,
				data: JSON.stringify(id),
				contentType: "application/json; charset=utf-8", 
				dataType: "json", 
			}).done(function(resp){
				// 성공 
				alert("추천했습니다.");
				location.href=`/board/${id}`;
			}).fail(function(error){
				// 실패
				alert(JSON.stringify(error))
			}); 
		} else {
			alert("이미 추천했습니다.");
			location.href=`/board/${id}`;
		}
	},
	
	unlike:function(likeCount){  
		var id = $("#id").text(); 
		
		if(likeCount == undefined){
			$.ajax({ 
				type:"POST",
				url: "/api/boardunlike/"+id,
				data: JSON.stringify(id),
				contentType: "application/json; charset=utf-8", 
				dataType: "json", 
			}).done(function(resp){
				// 성공 
				alert("비추천했습니다.");
				location.href=`/board/${id}`;
			}).fail(function(error){
				// 실패
				alert(JSON.stringify(error))
			}); 
		} else {
			alert("이미 추천했습니다.");
			location.href=`/board/${id}`;
		}
	},

 

 

5. BoardApiController에서 받아준다.

	@PostMapping("/api/boardlike/{id}")
	public ResponseDto<Integer> like(@PathVariable("id") int boardId, @AuthenticationPrincipal PrincipalDetail principal){
		User user = userRepository.findByUsername(principal.getUsername()).orElseThrow(()->{
			return new IllegalArgumentException("유저 찾기 실패 : 아이디를 찾을 수 없습니다.");
		});  
		LikeCount likeCount = likeCountRepository.like(user.getId(), boardId);
		if(likeCount == null) {
			boardService.추천(boardId); 
			Board board = boardRepository.findById(boardId).orElseThrow(()->{
				return new IllegalArgumentException("글 상세보기 실패 : 아이디를 찾을 수 없습니다.");
			});  
			likeCountService.추천유무(board, user);
		}
		return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);
	}
	
	@PostMapping("/api/boardunlike/{id}")
	public ResponseDto<Integer> unlike(@PathVariable("id") int boardId, @AuthenticationPrincipal PrincipalDetail principal){
		User user = userRepository.findByUsername(principal.getUsername()).orElseThrow(()->{
			return new IllegalArgumentException("유저 찾기 실패 : 아이디를 찾을 수 없습니다.");
		});  
		LikeCount likeCount = likeCountRepository.like(user.getId(), boardId);
		if(likeCount == null) {
			boardService.비추천(boardId); 
			Board board = boardRepository.findById(boardId).orElseThrow(()->{
				return new IllegalArgumentException("글 상세보기 실패 : 아이디를 찾을 수 없습니다.");
			});  
			likeCountService.추천유무(board, user);
		}
		return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);
	}

 

 

6. boardService에서 각각의 추천/비추천 메소드를 만들어서 처리

	@Transactional
	public void 추천(int id) {
		Board board = boardRepository.findById(id).orElseThrow(()->{
			return new IllegalArgumentException("글 찾기 실패 : 아이디를 찾을 수 없습니다.");
		}); 
		int cnt = board.getBlike() + 1; 
		board.setBlike(cnt); 
	}
	
	@Transactional
	public void 비추천(int id) {
		Board board = boardRepository.findById(id).orElseThrow(()->{
			return new IllegalArgumentException("글 찾기 실패 : 아이디를 찾을 수 없습니다.");
		}); 
		int cnt = board.getBlike() - 1; 
		board.setBlike(cnt); 
	}
	@Autowired
	private LikeCountRepository likeCountRepository;
	
	
	@Transactional
	public void 추천유무(Board board, User user) {  
		LikeCount likeCount = new LikeCount();
		likeCount.setBoard(board);
		likeCount.setUser(user);
		likeCountRepository.save(likeCount);
	} 

 

7. 게시글 상세페이지를 가져올때 likeCount테이블의 값을 가져와야 추천/비추천을 했는지 안했는지 알수있다.

	@GetMapping("/board/{id}")
	public String findById(@PathVariable int id, Model model, @AuthenticationPrincipal PrincipalDetail principal) {
		User user = userRepository.findByUsername(principal.getUsername()).orElseThrow(()->{
			return new IllegalArgumentException("유저 찾기 실패 : 아이디를 찾을 수 없습니다.");
		});  
		LikeCount likeCount = likeCountRepository.like(user.getId(), id);
		model.addAttribute("board", boardService.글상세보기(id)); 
		if(likeCount != null)
			model.addAttribute("likeCount", likeCount.getId()); 
		boardService.조회수(id);
		return "board/detail";
	}

 

 

 

 

 

8. 결과

추천 버튼 누르면

 

추천 + 1
비추천 버튼 누르면
추천 -1