Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 네트워크 설정
- 자료구조와 함께 배우는 알고리즘 입문
- 친절한SQL튜닝
- 페이징
- iterator
- d
- GIT
- resttemplate
- 알파회계
- 서버설정
- 스프링 시큐리티
- 자바편
- 티스토리 쿠키 삭제
- 리눅스
- 구멍가게코딩단
- 이터레이터
- network configuration
- ㅒ
- baeldung
- 코드로배우는스프링웹프로젝트
- 코드로배우는스프링부트웹프로젝트
- 처음 만나는 AI 수학 with Python
- 데비안
- Kernighan의 C언어 프로그래밍
- 처음 만나는 AI수학 with Python
- /etc/network/interfaces
- 선형대수
- 자료구조와함께배우는알고리즘입문
- 목록처리
- 스프링부트핵심가이드
Archives
- Today
- Total
bright jazz music
[bootBoard] N:1(다대일) 연관관계: 9-4. 프로젝트 적용: 게시물 삭제 처리 본문
Framework/Spring
[bootBoard] N:1(다대일) 연관관계: 9-4. 프로젝트 적용: 게시물 삭제 처리
bright jazz music 2022. 10. 7. 21:18삭제에 대한 고민
- 실제 개발에서는 삭제 처리에 대한 고민 필요
- 댓글이 있는 게시글은 게시물이 삭제될 시 거기에 달린 댓글까지 동의 없이 삭제되기 때문.
- 따라서 실무에서는 게시물에 상태(state) 칼럼을 지정하고 이를 변경하는 형태로 처리하는 것이 일반적
- 예를 들면 삭제 처리 시 실제로 삭제되는 것이 아닌 게시글의 상태가 "삭제"로 처리 된다고 할 수 있음.
여기 예제에서는 게시글 삭제 시 게시글과 댓글 모두 삭제된다고 가정한다.
board 테이블에서 데이터 삭제 시 FK로 board 테이블을 참조하는 reply 테이블에서도 삭제가 일어나야 한다.
순서1 : 해당 게시물의 모든 댓글 삭제
순서 2: 해당 게시물 삭제
이것은 개별 과정이지만 하나의 과정으로 처리되어야 하므로 @Transaction을 사용해야 한다.
1. ReplyRepository.java에 댓글 삭제 추상 메서드 추가
ReplyRepository.java
//ReplyRepository.java
package com.example.bootboard.repository;
import com.example.bootboard.entity.Reply;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
public interface ReplyRepository extends JpaRepository<Reply, Long> {
//삭제처리 추가
@Modifying
@Query("delete from Reply r where r.board.bno =:bno ")
void deleteByBno(Long bno);
}
2. BoardService.java에 게시글 삭제 추상 메서드 추가
//BoardService.java
public interface BoardService {
Long register(BoardDTO dto);
//getList() : 목록처리
PageResultDTO<BoardDTO, Object[]> getList(PageRequestDTO pageRequestDTO);
//조회 처리
BoardDTO get(Long bno);
//게시글 삭제 기능 방금 추가
void removeWithReplies(Long bno);
default Board dtoToEntity(BoardDTO dto) {
Member member = Member.builder().email(dto.getWriterEmail()).build();
Board board = Board.builder()
.bno(dto.getBno())
.title(dto.getTitle())
.content(dto.getContent())
.writer(member)
.build();
return board;
}
//entityToDTO()
default BoardDTO entityToDTO(Board board, Member member, Long replyCount) {
BoardDTO boardDTO = BoardDTO.builder()
.bno(board.getBno())
.title(board.getTitle())
.content(board.getContent())
.regDate(board.getRegDate())
.modDate(board.getModDate())
.writerEmail(member.getEmail())
.writerName(member.getName())
.replyCount(replyCount.intValue()) //long으로 나오므로 int처리
.build();
return boardDTO;
}
}
3. BoardServiceImpl.java에서 오버라이드
//BoardServiceImpl.java
import org.springframework.transaction.annotation.Transactional;
import java.util.function.Function;
@Service
@RequiredArgsConstructor
@Log4j2
public class BoardServiceImpl implements BoardService {
private final BoardRepository repository; // 자동 주입 final
private final ReplyRepository replyRepository; //새롭게 추가
@Override
public Long register(BoardDTO dto) {
log.info(dto);
Board board = dtoToEntity(dto);
repository.save(board);
return board.getBno();
}
//목록처리
@Override
public PageResultDTO<BoardDTO, Object[]> getList(PageRequestDTO pageRequestDTO) {
log.info(pageRequestDTO);
Function<Object[], BoardDTO> fn =
(en -> entityToDTO((Board)en[0], (Member)en[1], (Long)en[2]));
//Board board, Member member, Long replyCount
Page<Object[]> result = repository.getBoardWithReplyCount(
pageRequestDTO.getPageable(Sort.by("bno").descending()));
return new PageResultDTO<>(result, fn);
}
//게시글 조회 처리
@Override
public BoardDTO get(Long bno) {
Object result = repository.getBoardByBno(bno);
Object[] arr = (Object[]) result;
return entityToDTO((Board) arr[0], (Member) arr[1], (Long) arr[2]);
}
//게시글 삭제 처리
@Transactional
@Override
public void removeWithReplies(Long bno) {
//댓글부터 삭제
replyRepository.deleteByBno(bno);
repository.deleteById(bno);
}
}
4. 테스트
우선 댓글이 여러 개 달린 게시글을 DB에서 확인
//BoardServiceTests.java
@SpringBootTest
public class BoardServiceTests {
@Autowired
private BoardService boardService;
//등록 처리 테스트
@Test
public void testRegister() {
BoardDTO dto = BoardDTO.builder()
.title("Test.")
.content("Test ...")
.writerEmail("user55@aaa.com") //현재 DB에 존재한느 회원 이메일
.build();
Long bno = boardService.register(dto);
}
//목록 처리 테스트
@Test
public void testList() {
PageRequestDTO pageRequestDTO = new PageRequestDTO();
PageResultDTO<BoardDTO, Object[]> result = boardService.getList(pageRequestDTO);
for(BoardDTO boardDTO : result.getDtoList()){
System.out.println(boardDTO);
}
}
//게시글 조회 처리 테스트
@Test
public void testGet() {
Long bno = 100L;
BoardDTO boardDTO = boardService.get(bno);
System.out.println(boardDTO);
}
//게시글 삭제 처리 테스트 : 방금 추가
@Test
public void testRemove(){
Long bno = 72L;
boardService.removeWithReplies(bno);
}
}
5. 결과
콘솔로그
2022-10-07 23:13:31.042 INFO 5604 --- [ Test worker] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2022-10-07 23:13:31.042 INFO 5604 --- [ Test worker] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2022-10-07 23:13:31.736 WARN 5604 --- [ Test worker] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2022-10-07 23:13:32.298 INFO 5604 --- [ Test worker] c.e.bootboard.service.BoardServiceTests : Started BoardServiceTests in 3.811 seconds (JVM running for 5.223)
Hibernate:
delete
from
reply
where
board_bno=?
Hibernate:
select
board0_.bno as bno1_0_0_,
board0_.moddate as moddate2_0_0_,
board0_.reg_date as reg_date3_0_0_,
board0_.content as content4_0_0_,
board0_.title as title5_0_0_,
board0_.writer_email as writer_e6_0_0_
from
board board0_
where
board0_.bno=?
Hibernate:
delete
from
board
where
bno=?
2022-10-07 23:13:32.521 INFO 5604 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2022-10-07 23:13:32.524 INFO 5604 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2022-10-07 23:13:32.529 INFO 5604 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
BUILD SUCCESSFUL in 19s
4 actionable tasks: 3 executed, 1 up-to-date
오후 11:13:32: Task execution finished ':test --tests "com.example.bootboard.service.BoardServiceTests.testRemove"'.
DB
'Framework > Spring' 카테고리의 다른 글
[bootBoard] N:1(다대일) 연관관계: 10-1 화면처리: 목록, 페이징 (0) | 2022.10.08 |
---|---|
[bootBoard] N:1(다대일) 연관관계: 9-5. 프로젝트 적용: 게시물 수정 처리 (0) | 2022.10.08 |
[bootBoard] N:1(다대일) 연관관계: 9-2. 프로젝트 적용: 게시물 목록 처리 (0) | 2022.10.05 |
[bootBoard] N:1(다대일) 연관관계: 9-1. 프로젝트 적용: 게시물 등록 처리 (0) | 2022.10.04 |
[bootBoard] N:1(다대일) 연관관계: 8-2. 조회 화면에 필요한 JPQL 생성 (0) | 2022.09.29 |
Comments