[스프링부트] 글 상세 보기

익명 블로그 V1 - 10
이나겸's avatar
Nov 18, 2024
[스프링부트] 글 상세 보기

[익명 게시글을 쓰는 블로그 만들기 10]


글 상세 보기 그림 그리기(View)

src - main - resources - templates - detail.mustache파일 생성

notion image
 

detail.mustache 파일 - 글 상세 보기 view

  • mustache 문법 : 중괄호 두 개로 지정된 키 값과 필드명을 감쌈 ⇒ 값 가져오기
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Document</title> </head> <body> <nav> <!-- 헤더가 네비게이션 역할을 할거니까 --> <ul> <li> <a href="#">홈</a> </li> <li> <a href="#">글쓰기</a> </li> </ul> </nav> <hr> <section> <div> 번호: {{model.id}}<br> 제목: {{model.title}}<br> 내용: {{model.content}}<br> 작성일: {{model.createdAt}}<br> </div> </section> </body> </html>
 

BoardController 클래스

  • @GetMapping("/board/{id}")
    • URL 경로에서 중괄호로 감싼 값(id)을 메서드에서 @PathVariable("id")을 이용하여 int id 형태로 받을 수 있음
  • BoardService의 게시글 상세 보기 메서드를 통해 DetailDTO 객체로 정보를 받아 model에 저장하고 view로 전달
@RequiredArgsConstructor // final이 붙어있는 필드에 대한 생성자를 만들어줌 @Controller public class BoardController { private final BoardService boardService; /** * 주소 형태로 데이터 받기 :주소는 모두 where절에 걸림(where절은 쿼리문 조건절을 말한다) * 쿼리스트링(where절): /board?title=바다 (제목이'바다'인 글을 찾아줘) -기본키나 유니크 하지않을 때. ?key=value 형태. &(and)사용가능 * 패스변수(where절): /board/1 (id값이 1인 글을 찾아줘) -유니크(pk)할 때. URL의 경로 일부를 변수로 사용 * * RESTful API 설계 : 주소로 자원을 찾는 방법. 대화처럼 느껴져야 한다 쿼리스트링과 패스변수를 적절히 혼합하여 사용 */ @GetMapping("/board/{id}") // get 요청 public String detail(@PathVariable("id") int id, Model model) { BoardResponse.DetailDTO boardDetail = boardService.게시글상세보기(id); model.addAttribute("model", boardDetail); return "detail"; // view } }
 

BoardResponse 클래스 - DetailDTO 클래스

  • Board 객체를 매개변수로 받아 DetailDTO 생성
  • 작성일인 createAt 필드는 MyDate 클래스의 formatToStr 메서드를 호출하여 지정된 날짜 형식으로 변환
    • "yyyy.MM.dd" ⇒ 2024.11.18 형식
    • 밑의 날짜 포맷 변환 유틸 활용 참고
public class BoardResponse { @Data public static class DetailDTO { private int id; private String title; private String content; private String createdAt; public DetailDTO(Board board) { this.id = board.getId(); this.title = board.getTitle(); this.content = board.getContent(); this.createdAt = board.getCreatedAt() .toLocalDateTime() .format(DateTimeFormatter.ofPattern("yyyy.MM.dd")); } } }
 

날짜 포맷 변환 유틸 활용 참고

[유틸 패키지 만들기]

  • 패키지 이름 옆에 언더바 붙여 _core 패키지 만들어서 제일 위로 정렬 시킴
  • _core 패키지 안에 util 패키지를 만들고 MyDate.java 클래스 생성
notion image
 

[MyDate 클래스 - 유틸리티 클래스]

  • 날짜 관련 기능을 재사용 가능하도록 모은 유틸리티 클래스
  • static 사용하여 객체를 생성할 필요 없이 메서드를 클래스 이름으로 직접 호출 가능
  • SimpleDateFormat(”yyyy.MM.dd”)
    • 날짜 형식 지정하여 날짜를 문자열로 변환하는 클래스의 생성자
    • 날짜를 연도 4자리. 월 2자리. 일 2자리 형식으로 변환하는 패턴
  • format() 메서드
    • Timestamp 타입의 데이터를 sdf의 패턴을 사용해 문자열로 변환
public class MyDate { public static String formatToStr(Timestamp createdAt){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd"); String formattedDate = sdf.format(createdAt); return formattedDate; } }
 

[MyDateTest 클래스 - 테스트 클래스]

  • given
    • 테스트를 위한 입력 값을 설정
    • Timestamp 타입의 데이터를 현재 시간으로 생성하여 메서드에 전달할 입력값 준비
  • when
    • 테스트할 메서드 실행
    • Timestamp 타입의 데이터를 “yyyy.MM.dd” 형식의 문자열로 변환하는 메서드 실행
  • then
    • 결과 검증 ⇒ 출력으로 결과 검증하는 방식 채택
@Data public static class DetailDTO { private int id; private String title; private String content; private String createdAt; public DetailDTO(Board board) { this.id = board.getId(); this.title = board.getTitle(); this.content = board.getContent(); this.createdAt = MyDate.formatToStr(board.getCreatedAt()); } }

 

BoardService 클래스

  • boardRepository의 findById 메서드를 호출해 게시글 정보를 가져와 Board에 저장
  • 해당 정보로 DetailDTO 생성하여 반환
@RequiredArgsConstructor @Service public class BoardService { private final BoardRepository boardRepository; public BoardResponse.DetailDTO 게시글상세보기(int id) { Board board = boardRepository.findById(id); return new BoardResponse.DetailDTO(board); } }
 

BoardRepository 클래스

  • EntityManeger의 createNativeQuery 메서드를 사용하여 쿼리 생성 ⇒ 쿼리문에서 값은 ?로 설정
  • setParameter 메서드를 사용하여 ?에 인덱스와 값 설정
    • 인덱스는 1부터 시작
  • getSongleResult() 메서드를 호출하여 결과를 Object로 받아 Board로 다운캐스팅 후 반환
    • 테이블에서 하나의 행만 반환할 때 사용되며 반환값은 Object 타입
@RequiredArgsConstructor @Repository public class BoardRepository { private final EntityManager entityManager; public Board findById(int id) { Query q = entityManager.createNativeQuery("select * from board_tb where id = ?", Board.class); q.setParameter(1, id); return (Board) q.getSingleResult(); } }
 

웹 실행

  • 5번 게시글의 상세보기를 클릭하면 detail.mustache 파일에 작성한대로 글 상세보기 화면에 나타남
  • controller에 글 상세보기 요청은 /board/{id}로 매핑한것을 주소창의 url로 확인 할 수 있음
notion image
notion image
 
 
Share article

Nakyeom's Study