✏️ 고려사항
- 질문 글에 '좋아요' 추가.
- 한 건의 질문에 '좋아요' 한번만 추가.
- 좋아요 눌렀다가 한 번 또 누르면 좋아요 취소
- 취소된 좋아요는 DB에서 삭제
- 질문글에 좋아요 개수 표시
☘️ 구현내용
board 에 추가 해야 함. like는 객체와 상태를 저장할 repository 만 필요.
좋아요를 누른다 > service 로직 create like, control 로직 post like.
- Controller
1. board id 를 받아서 board 확인.
2. 좋아요를 누르는 사람이 누구인지 member id 는 dto로 받음. --- context authentication.
3. 좋아요 만들기. service 로직.
4. 리턴은 성공했다만 보내도 될 듯.
- Service
* 여기가 진짜 어려웠음.
1. 좋아요하면서 받은 board 와 member 가 유효한지 확인해야 함.
2. board 에 like 가 없으면 만들어야 함. DB에 저장.
// 비정규화.
3. 동시에 count 증가 시키면서 board 와 member 저장. 보드에도 like 저장. 서로 영향을 주어야 되니까 cascade.
4. board 에 like 가 있으면 지워줘야 함. DB에도 지워야 함.
5. ⭐️ 지울 때, cascade 해서 같이 저장되어 있는 board 의 like 도 지워야 함.⭐️ !!!!!!!!!!!!!!!!!!!!!!!!!!!
6. 동시에 count도 1 내려야 함. 이 상태는 board 에서 가지고 있음.
- Repository
* 안 건드려도 되는 줄 알았지만. 쿼리메서드를 활용해서 verify 를 repository 에서 할 수 있는 게 있음..!!!
findBy + 컬럼명을 사용하면 컬럼명과 일치하는 데이터를 찾는 조건을 추가함.
1. board 와 member 를 받아서, 일치하는 like 만 데리고 와라.
2. DB에서 가지고 올 때는 Optional 임.
Optional<Like> findByMemberAndBoard(Member member, Board board);
[Java] Spring Boot Jpa findBy 단일, 여러개 조건 검색 사용법
Spring Data Jpa 쿼리 메소드란?Spring-data-jpa의 JpaRepository는 메소드 이름 규칙에 따라 쿼리를 만들어주는 기능이 있습니다.쿼리 메소드 기능을 사용해서 AND 조건, OR 조건 등 여러 조건을 사용해서 쿼
priming.tistory.com
JPA로 원하는 매개변수로 findBy 메소드 생성하기
기본제공 findById(PK) 메소드 public Optional getMember(Long idx) { return memberRepository.findById(idx); } JPA에서 ID값을 파라미터로 SELECT 할 수 있는 기본 findById 메소드를 제공한다. 하지만 ID 필드가 아닌 다른 여
devfunny.tistory.com
🔎 코드작성
<Like Entity>
@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name = "likes")
public class Like {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long likeId;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "BOARD_ID")
private Board board;
public void setBoard (Board board) {
this.board = board;
if(board.getLike() != this) {
board.setLike(this);
}
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "MEMBER_ID")
private Member member;
public void setMember (Member member) {
this.member = member;
if(!member.getLikes().contains(this)) {
member.setLikes(this);
}
}
- @Table (name = "likes")
- like 는 Table 에서 예약어임. !! 바꿔주어야 함.
- Member, Board 받기.
- cascade 는 값을 받아야 하는 쪽에서 구현하기.
- 한 Member 당 Like 는 여러 개 달 수 있음. Member -일-다- Like 관계.
- 한 보드에 한 멤버는 Like 를 Board 를 달 수 있음. Like -일-일- Board 관계.
<LikeRepository>
public interface LikeRepository extends JpaRepository<Like, Long> {
Optional<Like> findByMemberAndBoard(Member member, Board board);
}
- 해당하는 member 와 board 에 맞는 like 를 데리고 와라.
<BoardService>
- like는 board에서 추가와 삭제를 하기 때문에 BoardService 에서 해야 함.
- 버튼을 누르면 해당 경로에 맞는. 요청을 수행하게 됨. html.
public void createLike (long boardId, Authentication authentication) {
// like 를 할 boardId 를 가지고 와서 board 를 데리고 옴.
Optional<Board> board = boardRepository.findById(boardId);
Board findBoard = board.orElseThrow(()
-> new BusinessLogicException(ExceptionCode.BOARD_NOT_FOUND));
// 받은 authentication의 principal 로 member 를 데리고 옴.
Optional<Member> member = memberRepository
.findByEmail((String) authentication.getPrincipal());
Member findMember = member.orElseThrow(()
-> new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND));
// 찾아놓은 board 와 member 로 like 를 가지고 옴.
Optional<Like> findLike = likeRepository
.findByMemberAndBoard(findMember, findBoard);
// 찾아놓은 like 가 있으면.
if( findLike.isPresent()) {
// delete 를 해라.
Like deleteLike = findLike.orElseThrow (()
-> new BusinessLogicException(ExceptionCode.LIKE_EXISTS));
findBoard.decreaseCount();
boardRepository.save(findBoard);
} else {
// like 가 없으면 like 를 더함.
Like addlike= new Like();
addlike.setBoard(findBoard);
addlike.setMember(findMember);
findBoard.increasedCount();
likeRepository.save(addlike);
}
}
- cascade 로 member 와 board 를 엮어 놨기 때문에 add 를 하면 자동으로 board 와 member 에 영향을 미침.
- 추가는 가능하지만, 삭제도 따로 메서드를 만들어 주어야 함.
<Like Entity> 추가
public void deleteBoard (Board board) {
this.board = null;
if(board.getLike() == this) {
board.deleteLike(this);
}
}
public void deleteMember (Member member) {
this.member = null;
if(member.getLikes().contains(this)) {
member.deleteLikes(this);
}
}
- board 에 like 가 있으면, delete like 를 하는데, board 에 null 을 저장한다.
- member 에 like 가 있으면, delete like 를 하는데, member 에 null 을 저장한다.
'Project > Coffee Board' 카테고리의 다른 글
[Coffee Board] 게시판 구현 4 - 비밀글 공개글 (0) | 2024.07.19 |
---|---|
[Coffee Board] 게시판 구현 3 - Authentication (0) | 2024.07.19 |
[Coffee Board] 게시판 구현 1 - @Mapper (0) | 2024.07.17 |