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