오늘의 할일 : 메인 페이지에서 댓글 기능 구현하기
댓글 번호
댓글에 넣은 이미지
댓글 단 시간
댓글을 단 유저 Idx
댓글을 단 게시물 Idx
댓글에 좋아요 갯수
댓글에 조회 갯수
댓글에 달린 댓글 갯수
적어 주지는 않았지만
@Getter ,@Setter ,@Entity 선언해주기
이 Entity도 DB에서 사용된 '-' 뒤에는 대문자로 구별
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long commentIdx;
@Column(nullable = false)
private String commentContent;
@Column(nullable = false)
private String commentImages;
@Column(nullable = false)
private LocalDateTime commentAt;
@Column(nullable = false)
private Long commentUseridx;
@Column(nullable = false)
private Long commentBoardidx;
@Column(nullable = false)
private Long commentLike;
@Column(nullable = false)
private Long commentView;
@Column(nullable = false)
private Long commentRelay;
}
@Tanscational 란
간단하게 설명해서 아래에 있는 코드들이 오류없이 진행이 되면 코드가 전체적으로 실행이되는 거다 그래서 만약 하나라도 오류가 있거나 빠진 코드가 있으면 실행이 되지 않고 오류가 발생한다
받아오는 파일 이름을 UUID로 랜덤하게 변경 -> 중복되는 이름이 있으면 오류가 발생하기 때문에
UUID -> 8-4-4-4-12의 5개 그룹으로 구분 으로
예시) 6fee0f11-9c5e-4340-845c-34e6b5e6dd3b 같이 가져온다
file.transferTo(savePath.toFile()) !실제로 파일을 저장하는 코드!
이후 commentRepository에 저장할떄 파일이름 isEmpty를 해준이유는 파일은 꼭 필수가 아니기 때문에 이미지 값이 없을경우 null을 반납하게 저장
게시글을 등록하면
Board에 해당하는 게시글에 BoardComment 값을 1 증가해줘야함
@Transactional
public Comment registerComment(Comment comment, MultipartFile[] files, Long boardidx, Long useridx) throws IOException {
List<String> fileNames = new ArrayList<>();
Board board = boardRepository.findByBoardIdx(boardidx);
board.setBoardComent(board.getBoardComent() + 1);
boardRepository.save(board); // 변경 사항 저장!
// files가 null이 아니고, 최소한 하나 이상의 파일이 있을 때만 실행
if (files != null && files.length > 0) {
for (MultipartFile file : files) {
if (!file.isEmpty()) { // 파일이 비어 있지 않을 때만 처리
String originalFileName = file.getOriginalFilename();
String fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
String uuid = UUID.randomUUID().toString();
String newFileName = uuid + "_" + fileExtension;
Path savePath = Paths.get(uploadURL, newFileName);
file.transferTo(savePath.toFile());
fileNames.add(newFileName);
}
}
}
comment.setCommentContent(comment.getCommentContent());
comment.setCommentImages(fileNames.isEmpty() ? null : String.join(",", fileNames));
comment.setCommentAt(LocalDateTime.now());
comment.setCommentUseridx(useridx);
comment.setCommentBoardidx(boardidx);
comment.setCommentLike(0L);
comment.setCommentRelay(0L);
comment.setCommentView(0L);
return commentRepository.save(comment);
}
@ModelAttribute("comment") -> model 값으로 자동으로 DTO랑 맵핑 해주기 위해서 사용
@RequestParam("commentfiles") -> html에서 name 값이 commentfiles를 저장해준다
@RequestParam -> html 에서 name 값이 boardidx 값을 Long boardidx에 저장
Principal principal -> 현재 로그인 정보를 가져온다 3장에서 로그인 할 때 loadUserByUsername 이랑 관련 이있음
이후 받아온 값을 Service로 보냄
Principal principal 란
사용자가 로그인을 하면 로그인한 유저의 username으로 loadUserByUsername() 에 전달 거기서
UserDetailsService에 DB에서 해당 유저를 찾고 반환
@RequestParam 원래는 파라미터 이름으로 바인딩을 한다 - 변수명과 파라미터명이 같을 때 가능
@RequestParam(속성)을 하면 요청하는 파라미터 이름과 변수명이 다를경우 html에서 name값을 가져와서 변수가 저장이된다 - HTML의 name과 Java 변수명이 다를 때 사용
@PostMapping("comment")
public String registerComment(@ModelAttribute("comment") Comment comment,
@Validated @RequestParam("commentfiles") MultipartFile[] files,
@RequestParam Long boardidx,
Principal principal,
RedirectAttributes redirectAttributes,
Model model) {
String username = principal.getName();
Member member = memberRepository.findByUserId(username)
.orElseThrow(() -> new RuntimeException("해당 유저를 찾을 수없습니다"));
try{
commentService.registerComment(comment,files,boardidx,member.getIdx());
redirectAttributes.addFlashAttribute("message","댓글을 작성했습니다");
return "redirect:/";
}catch (IllegalArgumentException e){
model.addAttribute("error",e.getMessage());
return "redirect:/";
}catch (Exception e){
model.addAttribute("error",e.getMessage());
return "redirect:/";
}
}
이는 기존에 게시글작성 리스트를 가져오는 MainContoller에서 작성을 한것이다
전부다 Map을 통해서 데이터를 Model로 보내준다
Map<Long,List> boardComments - 각 게시물에 달린 댓글 정보 가져오기
Map<Long,Member> CommentsMembers - 댓글을 작성한 유저의 정보를 가져오기
Map<Long,List> CommentImages - 댓글에 작성된 이미지 정보를 ',' 구별해서 가져오기
@GetMapping("/")
public String index(Model model,Principal principal) {
Member member = null;
if (principal != null) { // 사용자가 로그인한 경우
String username = principal.getName();
member = memberRepository.findByUserId(username)
.orElseThrow(() -> new RuntimeException("유저 정보를 찾을 수 없습니다"));
}
List<Board> boards = boardRepository.findAll(); // 전체 게시물 가져오기
Map<Long,Member> boardMembers = new HashMap<>(); // 게시물을 작성한 유저의 정보를 가져오기
Map<Long, List<String>> boardImages = new HashMap<>(); // 각 게시물에 해당하는 이미지 리스트 가져오기
Map<Long,List<Comment>> boardComments = new HashMap<>(); // 각 게시물에 달린 댓글 정보 가져오기
Map<Long,Member> CommentsMembers = new HashMap<>(); // 댓글을 작성한 유저의 정보를 가져오기
Map<Long,List<String>> CommentImages = new HashMap<>();
for (Board board : boards){
Long useridx = board.getBoardUseridx();
Member writer = memberRepository.findByIdx(useridx).orElseThrow(() -> new RuntimeException("게시물 작성자를 찾을 수 없습니다"));
boardMembers.put(board.getBoardIdx(), writer);
List<String> images = new ArrayList<>();
if (board.getBoardImages() != null && !board.getBoardImages().isEmpty()) {
images = Arrays.asList(board.getBoardImages().split(","));
}
boardImages.put(board.getBoardIdx(), images);
//게시물에 작성한 해당하는 댓글 정보 가져오기
List<Comment> comment = commentRepository.findByCommentBoardidx(board.getBoardIdx());
boardComments.put(board.getBoardIdx(), comment);
//댓글을 작성한 유저의 정보를 가져오기 및 이미지 값 나누기
for (Comment comment1 : comment) {
// 댓글을 단 유저의 정보를 가져오기
Long commentuseridx = comment1.getCommentUseridx();
Member members = memberRepository.findByIdx(commentuseridx).orElseThrow(() -> new RuntimeException("댓글 작성자를 찾을 수없습니다"));
CommentsMembers.put(comment1.getCommentIdx(), members);
// 해당 댓글에서작성한 이미지를 , 나누기
List<String> commentImages = new ArrayList<>();
if(comment1.getCommentImages() != null && !comment1.getCommentImages().isEmpty()) {
commentImages = Arrays.asList(comment1.getCommentImages().split(","));
}
CommentImages.put(comment1.getCommentIdx(), commentImages);
}
}
model.addAttribute("commentwirtes",CommentsMembers); // 댓글을 작성한 유저의 정보
model.addAttribute("commentList", boardComments);// 게시글에 작성한 댓글 정보
model.addAttribute("commentImages", CommentImages); // 댓글에 작성된 이미지를 , 로 나눠서 가져옴
model.addAttribute("member", member); // 현재 로그인한 유저의 정보
model.addAttribute("boardList", boards); // 모든 게실물
model.addAttribute("writers", boardMembers); // 게시물 작성자의 정보
model.addAttribute("boardImages", boardImages);
model.addAttribute("comment", new Comment());
model.addAttribute("board", new Board()); // 새 게시물 작서용 객체
return "index";
}
댓글 작성하기 전 -
댓글 작성한 후 -
이미지 가 있는 값도 -
DB에 저장된 값 -