spring 게시판 인텔리제이로 Ajax 댓글 기능 구현
상황 - 게시글 상세 페이지에서 댓글을 쓰는 상황
댓글 테이블 정의
create table comment_table(
id bigint primary key auto_increment,
commentWriter varchar(50),
commentContents varchar(200),
boardId bigint,
commentCreatedTime datetime default now(),
constraint fk_comment_table foreign key (boardId) references board_table(id) on delete cascade
);
boardId 는 board_table 의 id를 참조한다.
게시글이 지워지면 댓글도 지워주게 하기 위해서 on delete cascade 를 줬다
detail.jsp 에 댓글 폼을 추가 한다
<div>
<input type="text" id="commentWriter" placeholder="작성자">
<input type="text" id="commentContents" placeholder="내용">
<button id="comment-write-btn" onclick="commentWrite()">댓글작성</button>
</div>
<div id="comment-list">
<table>
<tr>
<th>댓글번호</th>
<th>작성자</th>
<th>내용</th>
<th>작성시간</th>
</tr>
<c:forEach items="${commentList}" var="comment">
<tr>
<td>${comment.id}</td>
<td>${comment.commentWriter}</td>
<td>${comment.commentContents}</td>
<td>${comment.commentCreatedTime}</td>
</tr>
</c:forEach>
</table>
</div>
댓글 작성하면 페이지 로딩 없이 비동기 방식으로 활용한다
비동기 방식으로 Ajax 로 사용할 것이다
폼 테그가 필요없고 사용자 입력을 받는 인풋 테그 2개
작성버튼을 클릭하면 commentWrite 함수를 호출하도록 구성했다
작성자와 댓글을 달수있도록 한다.
AjAX를 사용하기 위해 jQuery 사용하는 라이브러리를 가져온다
<script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
const commentWrite = () => {
const writer = document.getElementById("commentWriter").value;
const contents = document.getElementById("commentContents").value;
const board = '${board.id}';
$.ajax({
type: "post",
url: "/comment/save",
data: {
commentWriter: writer,
commentContents: contents,
boardId: board
},
dataType: "json",
success: function(commentList) {
console.log("작성성공");
console.log(commentList);
let output = "<table>";
output += "<tr><th>댓글번호</th>";
output += "<th>작성자</th>";
output += "<th>내용</th>";
output += "<th>작성시간</th></tr>";
for(let i in commentList){
output += "<tr>";
output += "<td>"+commentList[i].id+"</td>";
output += "<td>"+commentList[i].commentWriter+"</td>";
output += "<td>"+commentList[i].commentContents+"</td>";
output += "<td>"+commentList[i].commentCreatedTime+"</td>";
output += "</tr>";
}
output += "</table>";
document.getElementById('comment-list').innerHTML = output;
document.getElementById('commentWriter').value='';
document.getElementById('commentContents').value='';
},
error: function() {
console.log("실패");
}
});
댓글 작성을 하면 반드시 어떤 게시글의 작성을 했는지
게시글의 번호를 모델에 담아서 뿌려주는데
게시글의 아이디 값을 가져올수있다
해당 게시글에 해당 댓글번호는 db에서 만든다
Ajax로 controller 로 보내고
응답 결과에 따라 성공 실패 함수로 응답 받게 된다.
CommentDTO
package com.codingrecipe.board.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.sql.Timestamp;
@Getter
@Setter
@ToString
public class CommentDTO {
private Long id;
private String commentWriter;
private String commentContents;
private Long boardId;
private Timestamp commentCreatedTime;
}
댓글 번호 , 작성자 , 내용 , 해당 게시글에 대한 번호 , 댓글 작성 시간
CommentController
package com.codingrecipe.board.controller;
import com.codingrecipe.board.dto.CommentDTO;
import com.codingrecipe.board.service.CommentService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
@RequiredArgsConstructor
@RequestMapping("/comment")
public class CommentController {
@Autowired
private final CommentService commentService;
@PostMapping("/save")
public @ResponseBody List<CommentDTO> save(@ModelAttribute CommentDTO commentDTO) {
System.out.println("commentDTO = " + commentDTO);
commentService.save(commentDTO);
// 해당 게시글에 작성된 댓글 리스트를 가져옴
List<CommentDTO> commentDTOList = commentService.findAll(commentDTO.getBoardId());
return commentDTOList;
}
}
Ajax 응답을 줘야 하기 때문에 @ResponseBody 어노테이션을 적어준다
댓글이 작성되면 DTO가 담긴 리스트를 받아준다
findAll 은 해당 게시글에 작성된 댓글 리스트를 가져온다.
지금 작성된 게시글에 대한 댓글 리스트를 가져와야 하므로
매개변수로 게시물 번호가 필요하다
CommentService
package com.codingrecipe.board.service;
import com.codingrecipe.board.dto.CommentDTO;
import com.codingrecipe.board.repository.CommentRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class CommentService {
private final CommentRepository commentRepository;
public void save(CommentDTO commentDTO) {
commentRepository.save(commentDTO);
}
public List<CommentDTO> findAll(Long boardId) {
return commentRepository.findAll(boardId);
}
}
CommentRepository
package com.codingrecipe.board.repository;
import com.codingrecipe.board.dto.CommentDTO;
import lombok.RequiredArgsConstructor;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
@RequiredArgsConstructor
public class CommentRepository {
private final SqlSessionTemplate sql;
public void save(CommentDTO commentDTO) {
sql.insert("Comment.save", commentDTO);
}
public List<CommentDTO> findAll(Long boardId) {
return sql.selectList("Comment.findAll", boardId);
}
}
boardId를 넘겨줘야 해당 게시글에 해당하는 댓글 목록을 가져올 수 있다.
CommentMapper 를 등록하기 위해 mybatis-config.xml 에 등록한다
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias type="com.codingrecipe.board.dto.BoardDTO" alias="board"></typeAlias>
<typeAlias type="com.codingrecipe.board.dto.CommentDTO" alias="comment"></typeAlias>
</typeAliases>
</configuration>
CommentMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Comment">
<insert id="save" parameterType="comment">
insert into comment_table(commentWriter, commentContents, boardId)
values(#{commentWriter}, #{commentContents}, #{boardId})
</insert>
<select id="findAll" parameterType="Long" resultType="comment">
select * from comment_table where boardId=#{boardId} order by id desc
</select>
</mapper>
parameterType 으로 게시물번호 , resultType 으로 댓글 목록
작성한 댓글 데이터가 넘어오는것을 확인할 수 있다