SpringBoot
[Spring] #9. 게시판 만들기 _ 댓글작성/수정/삭제
도하루박
2022. 12. 30. 23:23
반응형
REPLY TABLE 생성
CREATE SEQUENCE SEQ_REPLY;
CREATE TABLE TBL_REPLY(
REPLY_NUMBER NUMBER CONSTRAINT PK_REPLY PRIMARY KEY,
REPLY_CONTENT VARCHAR2(1000),
REPLY_WRITER VARCHAR2(500),
REPLY_REGISTER_DATE DATE DEFAULT SYSDATE,
REPLY_UPDATE_DATE DATE DEFAULT SYSDATE,
BOARD_NUMBER NUMBER,
CONSTRAINT FK_REPLY FOREIGN KEY(BOARD_NUMBER)
REFERENCES TBL_BOARD(BOARD_NUMBER) ON DELETE CASCADE
);
ReplyVO
@NonNull
외부에서 반드시 받아야 할 것
@Component
@Data
@RequiredArgsConstructor @NoArgsConstructor
public class ReplyVO {
private Long replyNumber;
@NonNull
private String replyContent;
@NonNull
private String replyWriter;
private String replyRegisterDate;
private String replyUpdateDate;
@NonNull
private Long boardNumber;
}
ReplyMapper.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="com.example.app.mapper.ReplyMapper">
// 등록
<insert id="insert">
INSERT INTO TBL_REPLY(REPLY_NUMBER, REPLY_CONTENT, REPLY_WRITER, BOARD_NUMBER)
VALUES(SEQ_REPLY.NEXTVAL, #{replyContent}, #{replyWriter}, #{boardNumber})
</insert>
// 전체조회
<select id="selectAll" resultType="replyVO">
SELECT REPLY_NUMBER, REPLY_CONTENT, REPLY_WRITER, REPLY_REGISTER_DATE, REPLY_UPDATE_DATE, BOARD_NUMBER
FROM
(
SELECT ROWNUM R, REPLY_NUMBER, REPLY_CONTENT, REPLY_WRITER, REPLY_REGISTER_DATE, REPLY_UPDATE_DATE, BOARD_NUMBER
FROM
(
SELECT REPLY_NUMBER, REPLY_CONTENT, REPLY_WRITER, REPLY_REGISTER_DATE, REPLY_UPDATE_DATE, BOARD_NUMBER
FROM TBL_REPLY
WHERE BOARD_NUMBER = #{boardNumber}
ORDER BY REPLY_NUMBER DESC
)
<![CDATA[
WHERE ROWNUM <= #{criteria.page} * #{criteria.amount}
)
WHERE R > (#{criteria.page} - 1) * #{criteria.amount}
]]>
</select>
// 수정
<update id="update">
UPDATE TBL_REPLY
SET REPLY_CONTENT = #{replyContent}, REPLY_WRITER = #{replyWriter}, REPLY_UPDATE_DATE = SYSDATE
WHERE REPLY_NUMBER = #{replyNumber}
</update>
//삭제
<delete id="delete">
DELETE FROM TBL_REPLY
WHERE REPLY_NUMBER = #{replyNumber}
</delete>
//조회
<select id="select" resultType="replyVO">
SELECT REPLY_NUMBER, REPLY_CONTENT, REPLY_WRITER, BOARD_NUMBER, REPLY_REGISTER_DATE, REPLY_UPDATE_DATE FROM TBL_REPLY
WHERE REPLY_NUMBER = #{replyNumber}
</select>
//갯수
<select id="getTotal" resultType="_int">
SELECT COUNT(REPLY_NUMBER) FROM TBL_REPLY
WHERE BOARD_NUMBER = #{boardNumber}
</select>
</mapper>
ReplyMapper.java
@Mapper
public interface ReplyMapper {
public void insert(ReplyVO replyVO);
public List<ReplyVO> selectAll(@Param("boardNumber") Long boardNumber, @Param("criteria") Criteria criteria);
public void update(ReplyVO replyVO);
public void delete(Long replyNumber);
public ReplyVO select(Long replyNumber);
public int getTotal(Long boardNumber);
}
ReplyDAO
@Repository
@RequiredArgsConstructor
public class ReplyDAO {
private final ReplyMapper replyMapper;
public void save(ReplyVO replyVO){
replyMapper.insert(replyVO);
}
public List<ReplyVO> findAll(Long boardNumber, Criteria criteria){
return replyMapper.selectAll(boardNumber, criteria);
}
public void setReplyVO(ReplyVO replyVO){
replyMapper.update(replyVO);
}
public void remove(Long replyNumber){
replyMapper.delete(replyNumber);
}
public ReplyVO findById(Long replyNumber){
return replyMapper.select(replyNumber);
}
public int count(Long boardNumber){
return replyMapper.getTotal(boardNumber);
}
}
ReplyService
@Service
@RequiredArgsConstructor
public class ReplyService {
private final ReplyDAO replyDAO;
public void register(ReplyVO replyVO){
replyDAO.save(replyVO);
}
public List<ReplyVO> showAll(Long boardNumber, Criteria criteria){
return replyDAO.findAll(boardNumber, criteria);
}
public void modify(ReplyVO replyVO){
replyDAO.setReplyVO(replyVO);
}
public void remove(Long replyNumber){
replyDAO.remove(replyNumber);
}
public ReplyVO show(Long replyNumber){
return replyDAO.findById(replyNumber);
}
public int count(Long boardNumber){
return replyDAO.count(boardNumber);
}
}
ReplyController
@RequestBody 제이슨으로 전달 받겠다는 어노테이션이다.
결론은 PostMapping의 /new를 사용하면 "write success"를 받을 수 있다는 것을 알 수 있다.
// 추가
@PostMapping("/new")
public String write(@RequestBody ReplyVO replyVO){
replyService.register(replyVO);
return "write success";
}
Rest 확인하기 위해 Postman을 사용하였다.
POST 방식을 선택하고 경로 작성후 JSON으로 Send하면 리턴값인 "write success" 나오면 성공
Oracle DB에 잘 insert 되었다.
// 전체 조회
@GetMapping("/list/{boardNumber}/{page}")
public ReplyDTO list(@PathVariable("boardNumber") Long boardNumber, @PathVariable int page){
return new ReplyDTO(replyService.showAll(boardNumber, new Criteria().create(page, 10)), replyService.count(boardNumber));
}
Rest에서는 경로에 데이터를 입력할 수 있기 때문에 {boardNumber}를 전달하였다.
@PathVariable : 경로에 데이터가 있을 때 사용한다.
// 수정
@PostMapping("/modify")
public void modify(@RequestBody ReplyVO replyVO){
replyVO.setReplyWriter(Optional.ofNullable(replyVO.getReplyWriter()).orElse(replyService.show(replyVO.getReplyNumber()).getReplyWriter()));
replyService.modify(replyVO);
}
Optional은 JDK8부터 지원되는 검증 클래스이며, ofNullable(Object)로 사용한다.
ifPresent()를 사용하여 null 여부 검사가 가능하며, null이 아니라면 기존 Object 객체를 그대로 사용한다.
orElse를 사용하면 null일 경우 대체할 객체를 작성할 수 있다.
// 댓글 삭제
@DeleteMapping("/{replyNumber}")
public void remove(@PathVariable Long replyNumber){
replyService.remove(replyNumber);
}
// 댓글 1개 조회
@GetMapping("/{replyNumber}")
public ReplyVO show(@PathVariable Long replyNumber){
return replyService.show(replyNumber);
}
반응형