코드로 배우는 스프링부트 웹 프로젝트 Day 16
/* Annotation들은 스프링부트 프로젝트의 Annotation 정리 페이지에 따로 정리해두었습니다. */
[ 게시물 조회 테스트 ]
BoardServiceTests 클래스 추가
@Test
public void testGet() {
Long bno = 100L;
BoardDTO boardDTO = boardService.get(bno);
System.out.println(boardDTO);
}
[ 게시물 삭제 처리 ]
게시물을 지우는 상황에서 게시물에 댓글이 없다면, 게시물의 작성자가 삭제하면 문제가 없지만, 게시물에 댓글이 있다면, 해당 댓글의 사용자들의 동의 없이 삭제되기 때문에 문제가 발생함
=> 실제 개발에서는 게시물의 상태를 칼럼으로 지정하고, 해당 상태를 변경하는 형태로 처리하는 것이 일반적인 방식
하지만, 예제에서는 이를 고민하지 않고 게시물을 삭제할 수 있도록 한다고 한다..
게시물을 삭제할 때, FK로 게시물을 참조하고 있는 reply 테이블도 삭제해야만 함
따라서, 게시물의 댓글들을 삭제하고, 게시물을 삭제하는 순서로 진행되어야 하며, 위 작업이 하나의 트랜잭션으로 처리되어야 함
ReplyRepository 인터페이스 수정
public interface ReplyRepository extends JpaRepository<Reply, Long> {
@Modifying
@Query("delete from Reply r where r.board.bno =:bno ")
void deleteByBno(Long bno);
}
JPQL을 이용해서 update, delete 를 실행하기 위해서는 @Modifying 을 같이 추가해야 함
BoardService 인터페이스 추가
public interface BoardService {
Long register(BoardDTO dto);
PageResultDTO<BoardDTO, Object[]> getList(PageRequestDTO pageRequestDTO); //목록 처리
BoardDTO get(Long bno);
void removeWithReplies(Long bno); // 삭제기능
```
}
BoardServiceImpl 클래스 수정
public class BoardServiceImpl implements BoardService{
private final BoardRepository repository; // 자동 주입 final
private final ReplyRepository replyRepository;
```
@Transactional
@Override
public void removeWithReplies(Long bno) { // 삭제 기능 구현, 트랜잭션 추가
// 댓글부터 삭제
replyRepository.deleteByBno(bno);
repository.deleteById(bno);
}
}
[ 삭제 테스트 ]
BoardServiceTests 클래스 추가
@Test
public void testRemove() {
Long bno = 1L;
boardService.removeWithReplies(bno);
}
1번 게시글의 댓글들을 삭제하도록 하는 테스트
reply 테이블이 먼저 삭제되고, board 테이블을 조회한 후에 삭제됨
[ 게시물 수정 처리 ]
게시물의 수정은 제목과 내용에 한해서 수정이 가능하도록 설정
필요한 부분만 변경하고 BoardRepository의 save()를 이용해서 처리
Board 클래스 추가
@ManyToOne(fetch = FetchType.LAZY) // 명시적으로 Lazy 로딩 지정
private Member writer; // 연관관계 지정
public void changeTitle(String title) {
this.title = title;
}
public void changeContent(String content) {
this.content = content;
}
BoardService 인터페이스 추가
public interface BoardService {
```
void modify(BoardDTO boardDTO);
}
BoardServiceImpl 클래스 추가
@Override
public void modify(BoardDTO boardDTO) {
Board board = repository.findById(boardDTO.getBno()).get();
board.changeTitle(boardDTO.getTitle());
board.changeContent(boardDTO.getContent());
repository.save(board);
}
BoardDTO를 받아 데이터를 수정하는 modify 메소드 구현
BoardServiceTests 추가
@Test
public void testModify() {
BoardDTO boardDTO = BoardDTO.builder()
.bno(2L)
.title("제목 변경합니다.")
.content("내용 변경합니다.")
.build();
boardService.modify(boardDTO);
}
원래 Board 객체를 조회하고 update문이 실행됨
[ 컨트롤러와 화면 처리 ]
PageRequestDTO와 PageResultDTO를 동일하게 처리했기 때문에 이전 장에서 작성한 코드를 거의 그대로 사용 가능
controller 패키지 추가 + BoardController 클래스 작성
BoardController 클래스
package org.zerock.board2.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.zerock.board2.service.BoardService;
@Controller
@RequestMapping("/board/")
@Log4j2
@RequiredArgsConstructor
public class BoardController {
private final BoardService boardService;
}