1. Board
@NoArgsConstructor
@AllArgsConstructor
@Getter
@ToString
@Table(name = "board_tb")
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
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;
}
}- 의미가 명확한 코드를 위해
setter대신update메서드를 구현하여 글 수정 시 사용한다.
@CreationTimestamp어노테이션을 사용하면 엔티티가 삽입될 때 자동으로 현재 시간이 해당 필드에 넣어준다.
2. SaveDTO
@Data
public static class SaveDTO {
private String title;
private String content;
public Board toEntity() {
Board board = new Board(null, title, content, null);
return board;
}
}- DTO 데이터를 JPA Repository가 처리할 수 있도록,
toEntity메서드를 구현해 JPA Entity로 매핑한다.
3. BoardRepository
@RequiredArgsConstructor
@Repository
public class BoardRepository {
private final EntityManager entityManager;
public void delete(int id) {
entityManager.createQuery("delete from Board b where id=:id").setParameter("id", id).executeUpdate();
}
public void save(Board board) {
entityManager.persist(board);
}
public List<Board> findAll() {
return entityManager.createQuery("select b from Board b order by b.id desc", Board.class).getResultList();
}
public Optional<Board> findById(int id) {
return Optional.ofNullable(entityManager.find(Board.class, id));
}
}createNativeQuery대신createQuery메서드를 사용하여 JPQL을 활용한 간결한 쿼리문을 작성한다.
persist메서드를 사용하여Board엔티티를 영속성 컨텍스트에 추가하고, 트랜잭션 커밋 시 DB에 저장된다.
find메서드를 사용하여 특정 ID로 DB에서 엔티티를 조회한다.
- 조회한 결과가 없을 경우
Optional을 사용하여null처리를 안전하게 한다.
update메서드는findById를 사용하여 JPA로 수정할 수 있으므로 삭제한다.
4. BoardService
@RequiredArgsConstructor
@Service
public class BoardService {
private final BoardRepository boardRepository;
@Transactional
public void 게시글수정(int id, BoardRequest.UpdateDTO updateDTO) {
Board board = boardRepository.findById(id).orElseThrow(() -> new RuntimeException("해당 id의 게시글이 없습니다 : " + id));
board.update(updateDTO.getTitle(), updateDTO.getContent());
}
public BoardResponse.UpdateFormDTO 게시글수정화면보기(int id) {
Board board = boardRepository.findById(id).orElseThrow(() -> new RuntimeException("해당 id의 게시글이 없습니다 : " + id));
return new BoardResponse.UpdateFormDTO(board);
}
@Transactional
public void 게시글삭제(int id) {
boardRepository.delete(id);
}
@Transactional
public void 게시글쓰기(BoardRequest.SaveDTO saveDTO) {
boardRepository.save(saveDTO.toEntity());
}
public BoardResponse.DetailDTO 게시글상세보기(int id) {
Board board = boardRepository.findById(id).orElseThrow(() -> new RuntimeException("해당 id의 게시글이 없습니다 : " + id));
return new BoardResponse.DetailDTO(board);
}
public List<BoardResponse.DTO> 게시글목록보기() {
return boardRepository.findAll().stream()
.map(BoardResponse.DTO::new)
.toList();
}
}findById메서드를 호출할 때orElseThrow를 사용하여 조회 실패 시 예외 처리를 했다.
게시글수정메서드에서는board객체를 수정한 후, 더티 체크로 DB에 자동으로 갱신된다.
게시글쓰기메서드에서는 DTO를 Entity로 변환하여 저장한다.
게시글목록보기메서드에서는 조회한 정보를 Stream API를 사용해 DTO로 변환한 후, 리스트로 반환한다.
Share article