250x250
Notice
Recent Posts
Recent Comments
Link
관심쟁이 영호
[ADYB] 게시판 댓글기능 구현 본문
반응형
오늘은 게시판에 댓글기능을 구현할 예정이다.
목차는 다음과 같다.
목차
- 도메인 설계 and 연관관계 매핑
- Controller 구현
- Repository 생성
- 뷰 구현
도메인
도메인 내용은 다음과 같다.
Reply
속성 | 기타 | 설명 |
Long sequenceId | 시퀀스 전략, Primary Key | - |
User user | ManyToOne 관계(user가 1) | 댓글 작성자 |
Board board | ManyToOne 관계(board가 1) | 댓글이 포함되는 게시글 |
Timestamp createDate | Timestamp | 작성일 |
String Content | - | 댓글 내용 |
@Data
@Entity(name = "reply")
public class Reply {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int replyId;
@NotNull
@NotBlank
@Size(min = 1, max = 255)
@Column(nullable = false, length = 120)
String content;
@ManyToOne
@JoinColumn(name="boardId")
private Board board;
@ManyToOne
@JoinColumn(name="userId")
private User user;
@CreationTimestamp
private Timestamp createDate;
};
Board
Board에 Reply 추가
@OneToMany(mappedBy = "board")
private List<Reply> reply;
User
User에 Reply 추가
@OneToMany(mappedBy = "user")
private List<Reply> replyList;
컨트롤러 구현
우선 전략은 다음과 같다.
- board view에 댓글을 form으로 생성한다.
- controller와 post매핑하여 조작되도록 한다.
코드로 살펴보자.
@Controller
@RequiredArgsConstructor
public class ReplyController {
@Autowired
private final ReplyService replyService;
@PostMapping("/reply_write")
public String replyWrite(@ModelAttribute Reply reply, Long boardId, @SessionAttribute(name = SessionConst.LOGIN_USER, required = false)
User user){
return replyService.replyWrite(reply, user, boardId);
}
@PostMapping("/reply_delete")
public String replyDelete(@ModelAttribute Reply reply, @SessionAttribute(name = SessionConst.LOGIN_USER, required = false)
User user){
return replyService.replyDelete(reply);
}
};
위 코드를 보면, 작성 및 삭제를 post로 나누어 놓았다.
이제 Repository를 만들고 컨트롤러에 적용해보자.
Repository 생성
Repository는 Spring JPA data를 이용한다.
ReplyRepository
public interface ReplyRepository extends JpaRepository<Reply, Long> {
};
Service 생성
ReplyService
@Service
@RequiredArgsConstructor
public class ReplyService {
@Autowired
private final ReplyRepository replyRepository;
@Autowired
private final BoardRepository boardRepository;
@Autowired
private final UserRepository userRepository;
public String replyWrite(Reply reply, User user, Long boardId){
User findUser = userRepository.findByUserId(user.getUserId());
Optional<Board> findBoard = boardRepository.findById(boardId);
reply.setBoard(findBoard.get());
reply.setUser(findUser);
replyRepository.save(reply);
return "home";
}
public String replyDelete(Reply reply){
replyRepository.delete(reply);
return "home";
}
};
Write 부분에서는 board, user을 설정해주고 저장했다.
Delete 부분에서는 해당 reply만 삭제해주었다.
(User, board는 어차피 mappedBy 처리라서 따로 처리해주지 않아도 된다.)
뷰 구현
기존에 있던 페이지에서 추가해보자!
기존페이지는 다음과 같다.
(Thymeleaf를 사용했다.)
<!DOCTYPE html>
<html th:replace="~{layouts/base :: layout(~{::title},~{::section})}"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>게시판 조회</title>
</head>
<body>
<section class="masthead text-center">
<div class="jumbotron" th:object="${board}">
<h1 class="display-4" th:text="${board.title}">Hello, world!</h1>
<br>
<hr>
<br>
<div th:each="path : ${board.userFileList}">
<br>
<img th:src="${path.filePath}" class="card-img-top" alt="..." style="width: 200px; height 300px;">
<br>
</div>
<br><hr><br>
<p class="lead" th:text="${board.content}">This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
<hr><br>
<p th:text="${board.user.userId}">It uses utility classes for typography and spacing to space content out within the larger container.</p>
<br><hr><br>
<!-- Reply Section -->
<div class="input-group mb-3">
<form id="reply" action="/reply_write" method="post">
<input type="text" id="content" name="content" class="form-control" placeholder="댓글을 입력해주세요.." aria-label="댓글을 입력해주세요.." aria-describedby="basic-addon2">
<input type="hidden" id="boardId" name="boardId" th:value="${board.boardId}">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="submit">등록</button>
</div>
</form>
</div>
<!-- Reply Section End -->
<p class="lead">
<a class="btn btn-primary btn-lg" href="/board" role="button">목록으로</a>
</p>
</div>
</section>
</body>
</html>
Reply 기능은 form으로 이루어져 있다.
Reply 기능의 내용은 content이고, hidden으로 정의되어있는 것은 해당 board의 id를 넘기는 것이다. (매핑에 필요하기 때문에)
기타 입터셉터 처리까지 해주었다!
끝!
300x250
'Project > ADYB - 쇼핑몰' 카테고리의 다른 글
[ADYB] 게시판 글쓰기 구현 ㅣ JPA + Spring Boot + Thymeleaf (1) | 2021.08.03 |
---|---|
[ADYB] Spring Boot ㅣ 로그아웃 구현하기 ㅣ 세션 만료시키기 (0) | 2021.08.03 |
[ADYB] Session이 없으면 특정페이지 접근못하게 하기 (0) | 2021.08.03 |
[#6] JPA를 이용한 로그인 (0) | 2021.08.03 |
Comments