즐겨찾기 추가/삭제 기능을 구현했다.
- method 하나에 즐겨찾기 추가/삭제 한 번에 구현
- post/delete method로 나눠서 구현
이 게시물은 1번으로 작업한 걸 올리는 거고, 추후에 2번으로 작업한 것을 올리려고 한다.
01. controller
@RequiredArgsConstructor
@Slf4j
@RestController
@RequestMapping("/board")
public class Board () {
private final BoardService boardService;
@Comment("즐겨찾기 추가 및 삭제")
@PostMapping("/favorite")
public ResponseEntity<ApiResult<String>> boardFavorite(Long boardId, @RequestParam(value = "enabled") Boolean enabled) {
boardService.boardFavorite(boardId, enabled);
ApiResult<String> response = ApiResult.<String>builder()
.code(ApiResultCode.succeed)
.build();
return new ResponseEntity<>(response, HttpStatus.OK);
}
}
- Long boardId
- 즐겨찾기 할 게시판 ID 번호
- Boolean enabled
- boolean 타입으로 true일 때는 즐겨찾기 추가, false일 때는 즐겨찾기를 삭제하기 위한 구분값으로 넣었다.
- boardService.boardFavorite(boardId, enabled);
- 파라미터로 `boardId, enabled` 넣고, service 호출
02. service
public class BoardService {
public void boardFavorite(Long boardId, Boolean enabled) {
// board_id 및 member_id 정보 조회
Board board = boardRepository.findById(boardId).orElseThrow(() -> new IllegalArgumentException("Not Found Board"));
Member member = memberRepository.findById(principal.getMemberId()).orElseThrow(() -> new IllegalArgumentException("Not Found Member"));
Long memberId = member.getId();
BoardFavorite boardFavoriteBoardAndMember = boardFavoriteRepository.findByBoardAndMemberId(board, memberId);
BoardFavorite boardFavoriteSort = boardFavoriteRepository.findFirstByMemberIdOrderBySortDesc(memberId); // sort 기준으로 정렬
Long sortNum = !ObjectUtils.isEmpty(boardFavoriteSort) ? boardFavoriteSort.getSort() + 1L : 1L;
if (enabled) {
if (boardFavoriteBoardAndMember == null) {
BoardFavorite boardFavorite = new BoardFavorite(board, memberId);
boardFavorite.setSort(sortNum);
boardFavoriteRepository.save(boardFavorite);
} else {
throw new IllegalArgumentException("FavoriteBoard already exists");
}
} else {
if (boardFavoriteBoardAndMember != null) {
boardFavoriteRepository.delete(boardFavoriteBoardAndMember);
} else {
throw new IllegalArgumentException("FavoriteBoard already deleted");
}
}
}
}
- `boardRepository`에서 board id를 조회함
- `memberRepository`에서 member id를 조회함
- `boardFavoriteRepository`에서 boardId와 memberId가 일치하는 튜플이 있는지 조회
- enabled == true 이고,
- `boardFavorieteBoardAndMember`가 null 값이면, 즐겨찾기 추가
- 이미 추가되어 있는 상태에서 다시 호출 시, exception
- enalbed == false 이고,
- `boardFavorieteBoardAndMember`가 null 값이 아니면, 즐겨찾기 해제
- 이미 삭제된 상태인데, 다시 삭제하려고 하면 exception
03. entity
@Entity
@DynamicInsert
@DynamicUpdate
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Table(indexes = {
@Index(name = "IDX_BOARD_FAVORITE__MEMBER_BOARD", columnList = "memberId,boardId")
})
public class BoardFavorite {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Positive
@Comment("PK")
private Long id;
@Comment("게시물 id")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "boardId")
@NotNull
private Board board;
@Comment("멤버 id")
@NotNull
private Long memberId;
@Comment("즐겨찾기 상태")
@NotNull
private boolean enabled; // true 즐겨찾기, false 즐겨찾기 취소
@Comment("정렬")
@NotNull
private Long sort;
@Comment("즐겨찾기 생성 날짜")
@NotNull
private ZonedDateTime created;
@Comment("즐겨찾기 수정 날짜")
private ZonedDateTime modified;
@PrePersist
public void prePersist() {
if (created == null) {
created = ZonedDateTime.now();
}
if (modified == null) {
modified = ZonedDateTime.now();
}
}
@PreUpdate
public void preUpdate() {
if (modified == null) {
modified = ZonedDateTime.now();
}
}
public BoardFavorite(Board board, Long memberId) {
this.board = board;
this.memberId = memberId;
this.enabled = true;
}
}
entity는 위와 같이 추가
index는 memberId와 boardId로 복합키를 줌
원래는 상태를 체크하려고, `enabled` 필드를 넣었었다.
하지만 즐겨찾기 해제 시에는 튜플 자체가 삭제되기 때문에, 필요 없다고 생각하여 추후에 삭제했다.
04. repository
public interface BoardFavoriteRepository extends JpaRepository<BoardFavorite, Long> {
BoardFavorite findByBoardAndMemberId(Board boardId, Long memberId);
BoardFavorite findFirstByMemberIdOrderBySortDesc(Long memberId);
}
repository는 위와 같다.
위와 같이 작성을 했고, 작동은 잘했다.
피드백을 여러 번 받았는데, 위도 그렇고 초반에도 그렇고 계속 받았던 피드백 중에 하나가 조건문을 지나치게 사용한다는 것이었다.
그리고 또 하나는 기존에 존재하던 다른 코드들이 추가/삭제를 한 메서드에 작성하고 있는 게 아니기 때문에 분리가 필요할 것 같다는 피드백을 받았다.
그렇게 해서 수정한 게 2번인 'post/delete' method를 구분해서 다시 작성한 코드이다.
추후 다른 게시물에 올릴 예정이다.
300x250
'Framekwork > SPRING' 카테고리의 다른 글
[SPRING BOOT] 즐겨찾기 추가/해제 코드 변천사 (0) | 2024.07.23 |
---|---|
[SPRING BOOT] 즐겨찾기 추가 및 해제 (삭제) method 분리 (0) | 2024.07.19 |
[Thymeleaf] config에 설정된 url 패턴을 타임리프 src 경로로 설정 (0) | 2024.07.10 |
[SPRING] @BeforeEach @AfterEach 어노테이션 (0) | 2024.04.17 |
[Swagger] https 접속 시 해당 서버만 목록에 나오게 하기 (0) | 2024.04.02 |