[익명 게시글을 쓰는 블로그 만들기 10]
글 상세 보기 그림 그리기(View)
src - main - resources - templates - detail.mustache파일 생성

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 클래스 생성

[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로 확인 할 수 있음


Share article