[Spring] 11/5 팀프로젝트 구현(마이페이지 북마크 완성, DTO 추가)
DTO 추가
다른 팀원이 일괄적으로 DTO를 만들어준다고 잘못 이해해서 DTO 없이 파일을 만들다가 각자 필요한 DTO는 알아서 만들어서 사용하면 된다고 해서 다시 DTO를 만들었다. 다른 파일은 생략하고 북마크 DTO는 다음과 같다. 닉네임 필드부터는 엔터티에 없지만 Service 계층에서 엔터티를 DTO로 바꾸는 과정에서 User의 정보를 가져와 세팅할 수 있도록 만들었다.
BookmarkDTO
// import 생략
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BookmarkDTO {
private Long boardId;
private Long userId;
@NotEmpty
private LocalDateTime bookmarkedDate;
private String userNickname;
private String title;
private String content;
private String purchaseLink;
private LocalDateTime regDate;
}
마이페이지 북마크
북마크가 복합키(board_id, user_id)를 가진 엔터티라서 북마크의 제목을 눌렀을 때, 북마크 페이지를 따로 만들어서 보여줘야할지, 존재하는 게시물의 링크로 바로 이동할 수 있게 할지 고민하다가 조장님과 회의해서 바로 게시물의 링크로 이동할 수 있도록 만들었다.
BookmarkRepository
// import 생략
public interface BookmarkRepository extends JpaRepository<BookMark, BookMarkId> {
Optional<BookMark> findById(BookMarkId bookmarkId);
void deleteById(BookMarkId bookmarkId);
List<BookMark> findByUserUserId(Long userId);
}
BookmarkService
// import 생략
@Service
@Data
@Transactional
@RequiredArgsConstructor
public class BookMarkServiceImpl implements BookMarkService {
private final BookmarkRepository bookmarkRepository;
@Override
public Optional<BookmarkDTO> readBookMark(BookMarkId bookMarkId) {
Optional<BookMark> bookmark = bookmarkRepository.findById(bookMarkId);
bookmark.ifPresent(b -> {
Hibernate.initialize(b.getBoard());
Hibernate.initialize(b.getUser());
});
return bookmark.map(this::convertEntityToDTO);
}
@Override
public List<BookmarkDTO> readUserBookmarks(Long userId) {
return bookmarkRepository.findByUserUserId(userId).stream()
.map(this::convertEntityToDTO)
.collect(Collectors.toList());
}
@Override
public void deleteBookMark(BookMarkId bookmarkId) {
bookmarkRepository.deleteById(bookmarkId);
}
private BookmarkDTO convertEntityToDTO(BookMark bookmark) {
return BookmarkDTO.builder()
.boardId(bookmark.getBoard().getBoardId())
.userId(bookmark.getUser().getUserId())
.bookmarkedDate(bookmark.getBookmarkedDate())
.userNickname(bookmark.getUser().getNickname())
.title(bookmark.getBoard().getTitle())
.content(bookmark.getBoard().getContent())
.purchaseLink(bookmark.getBoard().getPurchaseLink())
.regDate(bookmark.getBoard().getRegDate())
.build();
}
}
BookmarkController
// import 생략
@Controller
//@RequestMapping("/bookmark")
@RequiredArgsConstructor
@Log4j2
public class BookmarkController {
private final BookMarkService bookMarkService;
// 북마크 게시물 하나
@GetMapping("/bookmark/{userId}/{boardId}")
public String readOneBookmark(@PathVariable("userId") Long userId,
@PathVariable("boardId") Long boardId,
Model model) {
BookMarkId bookmarkId = new BookMarkId(userId, boardId);
Optional<BookmarkDTO> bookmark = bookMarkService.readBookMark(bookmarkId);
if (bookmark.isPresent()) {
model.addAttribute("bookmark", bookmark.get());
} else {
// board가 없거나 북마크가 없는 경우 처리
model.addAttribute("errorMessage", "해당 게시물을 찾을 수 없습니다.");
log.error("Bookmark or Board not found for userId: {}, boardId: {}", userId, boardId);
}
return "/my/myBookmark";
}
// 사용자의 게시물 목록
@GetMapping("/myBookmarkList/{userId}")
public String readBookmarkList(@PathVariable("userId") Long userId, Model model) {
List<BookmarkDTO> bookMarks = bookMarkService.readUserBookmarks(userId);
model.addAttribute("bookmarks", bookMarks);
return "/my/myBookmarkList";
}
@PostMapping("/bookmarkDelete/{userId}/{boardId}")
public String deleteBookmark(@PathVariable("userId") Long userId,
@PathVariable("boardId") Long boardId) {
BookMarkId bookmarkId = new BookMarkId(userId, boardId);
bookMarkService.deleteBookMark(bookmarkId);
return "redirect:/myBookmarkList/" + userId;
}
}
화면 동작
마이페이지에서 내 북마크 -> 북마크 조회를 클릭하면 내가 북마크한 게시글 목록 화면이 출력된다. 제목을 클릭하면
삭제 버튼을 누르면 alert 창이 뜨면서 DB와 화면에서 모두 잘 지워지는 것을 확인했다.
조회수 증가 기능 추가
마이페이지에서 사용자가 작성한 게시글을 조회했을 때 조회수가 증가하는 기능을 추가했다.
BoardService 추가내용
// 조회수 증가
@Transactional
public void increaseVisitCount(Long boardId) {
Board board = boardRepository.findById(boardId)
.orElseThrow(() -> new IllegalArgumentException("Board not found"));
board.setVisitCount(board.getVisitCount() + 1);
boardRepository.save(board);
}
BoardController 추가내용
@GetMapping("/myBoard/{userId}/{boardId}")
public String readOneBoard(@PathVariable("boardId") Long boardId,
Model model) {
boardService.increaseVisitCount(boardId);
Optional<BoardDTO> board = boardService.readBoard(boardId);
if (board.isPresent()) {
model.addAttribute("board", board.get());
}
return "/my/myBoard";
}
댓글남기기