기존의 nativeQuery로 작성했던 Service 객체 내용들을 모두 JPA(Java Persistence API)를 사용한 예제로 변경하는 내용입니다.
게시글을 보기 전 해당 글을 먼저 보고 적용한 뒤 아래의 내용을 보는 것이 좋습니다.
변경된 Board 객체 내용
@NoArgsConstructor // DB에서 조회해서 가져온 ResultSet을 디폴트 생성자를 호출해서 new하고 값을 채워준다.
@AllArgsConstructor
@Getter
@Table(name = "board_tb")
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // Auto increment 와 동일
private Integer id;
private String title;
private String content;
@CreationTimestamp
private Timestamp createdAt;
public void update(String title, String content) {
this.title = title;
this.content = content;
}
}
- update 메서드 추가 (매개 변수로 전달 받은 title, content의 내용에 따라 필드의 title, content 값을 변경합니다.
- 어노테이션 추가 (@AllArgsConstructor, @CreationTimestamp 어노테이션이 추가되었습니다.)
@AllArgsConstructor : 클래스의 모든 필드에 대한 생성자를 자동으로 생성해줍니다.
@CreationTimestamp : Hibernate에서 제공하는 어노테이션으로, 엔티티가 생성된 시점을 자동으로 기록합니다.
변경된 BoardService(Service라고 통칭) 객체 내용
게시글상세보기 메서드 (id값으로 Board찾기)
public BoardResponse.DetailDTO 게시글상세보기(int id) {
Board board = boardRepository.findById(id)
.orElseThrow(() -> new RuntimeException("해당 id의 게시글이 없습니다 : " + id));
return new BoardResponse.DetailDTO(board);
}
- 설명:
- 게시글 조회:
boardRepository.findById(id)
를 통해id
에 해당하는Board
엔티티를 조회합니다. - 예외 처리:
Optional
이 반환되므로,orElseThrow
를 사용하여 게시글이 없으면RuntimeException
을 발생시킵니다. - DTO 반환: 조회된
Board
엔티티를BoardResponse.DetailDTO
로 변환하여 반환합니다.
- Detail :
- 데이터베이스에서
id
에 해당하는 게시글을 조회하여, 게시글이 존재하지 않으면 예외를 발생시키고, 존재하면 해당 게시글의 세부 정보를 포함한 DTO를 반환합니다.
게시글수정화면보기 메서드
public BoardResponse.UpdateFormDTO 게시글수정화면보기(int id) {
Board board = boardRepository.findById(id)
.orElseThrow(() -> new RuntimeException("해당 id의 게시글이 없습니다 : " + id));
return new BoardResponse.UpdateFormDTO(board);
}
- 설명:
- 게시글 조회:
boardRepository.findById(id)
를 통해id
에 해당하는Board
엔티티를 조회합니다. - 예외 처리:
Optional
이 반환되므로,orElseThrow
를 사용하여 게시글이 없으면RuntimeException
을 발생시킵니다. - DTO 반환: 조회된
Board
엔티티를BoardResponse.UpdateFormDTO
로 변환하여 반환합니다.
- Detail :
- 데이터베이스에서
id
에 해당하는 게시글을 조회하여, 게시글이 존재하지 않으면 예외를 발생시키고, 존재하면 수정 화면에 필요한 정보를 포함한 DTO를 반환합니다.
게시글쓰기 메서드
@Transactional
public void 게시글쓰기(BoardRequest.SaveDTO saveDTO) {
boardRepository.save(saveDTO.toEntity());
}
- 설명:
- DTO 변환:
saveDTO.toEntity()
를 호출하여SaveDTO
를Board
엔티티로 변환합니다. - 엔티티 저장:
boardRepository.save(board)
를 통해 변환된Board
엔티티를 데이터베이스에 저장합니다.
- Detail :
SaveDTO
객체를Board
엔티티로 변환하고, 이를 데이터베이스에 저장하여 새로운 게시글을 생성합니다.@Transactional
어노테이션 덕분에 트랜잭션이 시작되고 종료 시점에 커밋됩니다.
게시글수정 메서드
@Transactional
public void 게시글수정(int id, BoardRequest.UpdateDTO updateDTO) {
Board board = boardRepository.findById(id)
.orElseThrow(() -> new RuntimeException("해당 id의 게시글이 없습니다 : " + id));
board.update(updateDTO.getTitle(), updateDTO.getContent());
}
- 설명:
- 게시글 조회:
boardRepository.findById(id)
를 통해id
에 해당하는Board
엔티티를 조회합니다. - 예외 처리:
Optional
이 반환되므로,orElseThrow
를 사용하여 게시글이 없으면RuntimeException
을 발생시킵니다. - 게시글 수정: 조회된
Board
엔티티의update
메서드를 호출하여 제목과 내용을 수정합니다.
- Detail :
- 데이터베이스에서
id
에 해당하는 게시글을 조회하여, 게시글이 존재하지 않으면 예외를 발생시키고, 존재하면 수정된 제목과 내용으로 게시글을 업데이트합니다.@Transactional
어노테이션 덕분에 트랜잭션이 시작되고 종료 시점에 커밋됩니다. - 더티 체킹: 영속성 컨텍스트 내에서 엔티티의 상태가 변경되면, 트랜잭션이 커밋될 때 자동으로 변경 사항이 데이터베이스에 반영됩니다.
(알아서 update 쿼리를 전달하기 때문에 Repository 클래스에서 update 관련 메서드를 삭제한 이유이기도 합니다.)
수정된 BoardService (Service) 객체 결과
@RequiredArgsConstructor
@Service
public class BoardService {
private final BoardRepository boardRepository;
public List<BoardResponse.DTO> 게시글목록보기() {
List<BoardResponse.DTO> dtos = new ArrayList<>();
List<Board> boardList = boardRepository.findAll();
for (Board board : boardList) {
BoardResponse.DTO dto = new BoardResponse.DTO(board);
dtos.add(dto);
}
return dtos;
}
public BoardResponse.DetailDTO 게시글상세보기(int id) {
Board board = boardRepository.findById(id)
.orElseThrow(() -> new RuntimeException("해당 id의 게시글이 없습니다 : " + id));
return new BoardResponse.DetailDTO(board);
}
public BoardResponse.UpdateFormDTO 게시글수정화면보기(int id) {
Board board = boardRepository.findById(id)
.orElseThrow(() -> new RuntimeException("해당 id의 게시글이 없습니다 : " + id));
return new BoardResponse.UpdateFormDTO(board);
}
@Transactional
public void 게시글쓰기(BoardRequest.SaveDTO saveDTO) {
boardRepository.save(saveDTO.toEntity());
}
@Transactional
public void 게시글삭제(int id) {
boardRepository.delete(id);
}
@Transactional
public void 게시글수정(int id, BoardRequest.UpdateDTO updateDTO) {
Board board = boardRepository.findById(id)
.orElseThrow(() -> new RuntimeException("해당 id의 게시글이 없습니다 : " + id));
board.update(updateDTO.getTitle(), updateDTO.getContent());
} // 영속화된 객체 상태 변경 - update + commit => 더티 체킹
}
Share article