
1. jsp보다 mustache가 좋은 이유
- jsp
<%%>자바 코드를 적을 수 있어 자유도가 높음
- mustache
문법이 한정적 몇 개 없음
뷰에 자바 코드가 최소화 되서 좋음
컨트롤러에 다 만들어서 던지면 뷰를 순수 뷰로 만들 수 있음
6. Mustache 문법
- 핵심은 중괄호(
{{ }}
)를 사용하여 데이터를 표시
-
#
,/
,^
등의 제어 구조를 사용하여 조건문과 반복문을 표현
{{ 변수명 }} // 변수 출력
{{{ 변수명 }}} // 세션 출력
{{# 조건 }} // 조건문
<!-- 조건이 참일 때 표시할 내용 -->
{{/ 조건 }}
{{^ 배열 }} // 역반복문
<!-- 배열이 비어있을 때 표시할 내용 -->
{{/ 배열 }}
{{# 배열 }} // 반복문
<!-- 배열의 각 항목에 대한 내용 -->
{{/ 배열 }}
htmlCopy code{{! 주석 내용 }} // 주석
{{> 부분템플릿명 }} // 부분 템플릿 호출
{{& 변수명 }} // 변수 대체
{{ 변수명 || '기본값' }} // 변수의 디폴트 값 설정
2. currentPage = max) nextPage 비활성화
package shop.mtcoding.blog.board;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import shop.mtcoding.blog.user.User;
import java.util.List;
@RequiredArgsConstructor
@Controller
public class BoardController {
// HttpSession 객체를 참조
private final HttpSession session;
private final BoardRepository boardRepository; // DI
@GetMapping({"/", "/board"})
public String index(HttpServletRequest request, @RequestParam(defaultValue = "0") int page) {
User sessionUser = (User) session.getAttribute("sessionUser");
if (sessionUser == null) {
System.out.println("로그인 안된 상태입니다");
} else {
System.out.println("로그인 된 상태입니다");
}
// select * from board_tb order by id desc
List<Board> boardList = boardRepository.findAll();
request.setAttribute("boardList", boardList); // ("key", value)
int currentPage = page;
int nextPage = currentPage + 1;
int prevPage = currentPage - 1;
request.setAttribute("nextPage", nextPage);
request.setAttribute("prevPage", prevPage);
// 이것만 담으면 disable를 못한다.
// 현재 페이지가 퍼스트인지 라스트인지 만든다.
boolean first = currentPage == 0 ? true : false;
// select count(*) from board_tb
int boardTotalCount = boardRepository.findBoardTotalCount();
System.out.println(boardTotalCount);
int paging = 3;
int totalpage = boardTotalCount / paging;
boolean last = currentPage == totalpage ? true : false;
request.setAttribute("first", first);
request.setAttribute("last", last);
return "index";
}
@GetMapping("/board/saveForm")
public String saveForm() {
return "board/saveForm";
}
@GetMapping("/board/1")
public String detail() {
return "board/detail";
}
}
package shop.mtcoding.blog.board;
import lombok.RequiredArgsConstructor;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.List;
@RequiredArgsConstructor
@Repository
public class BoardRepository {
private final EntityManager em; // jpa가 제공해줌
// 조회니까 트랜잭션 필요없음
public List<Board> findAll(int page) { // 보드 테이블의 모든 것 가지고 오기
final int COUNT = 3;
int value = page*COUNT;
Query query = em.createNativeQuery("select * from board_tb order by id desc limit ?,?", Board.class);
query.setParameter(1, value);
query.setParameter(2, COUNT);
List<Board> boardList = query.getResultList(); // 여러건
return boardList;
} // 이 결과를 리퀘스트에 담고 뷰 화면 가서 뿌리기
public int findBoardTotalCount() {
Query query = em.createNativeQuery("select count(*) from board_tb");
int boardTotalCount= ((Number)query.getSingleResult()).intValue();
//System.out.println("boardTotalCount : "+boardTotalCount);
return boardTotalCount;
}
}



package shop.mtcoding.blog.board;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import shop.mtcoding.blog.user.User;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
@RequiredArgsConstructor
@Controller
public class BoardController {
private final HttpSession session;
private final BoardRepository boardRepository;
// http://localhost:8080?page=0
@GetMapping({ "/", "/board"})
public String index(HttpServletRequest request, @RequestParam(defaultValue = "0") int page) {
//System.out.println("페이지: " +page);
List<Board> boardList = boardRepository.findAll(page);
request.setAttribute("boardList", boardList); // 가방에 담음
int currentPage = page;
int nextPage = currentPage+1;
int prevPage = currentPage-1;
request.setAttribute("nextPage", nextPage);
request.setAttribute("prevPage", prevPage);
// 이것만 담으면 디세이브를 못한다.
// 현재 페이지가 퍼스트인지 라스트인지 만든다.
boolean first = currentPage == 0 ? true : false;
int boardTotalCount = boardRepository.findBoardTotalCount();
System.out.println(boardTotalCount);
int pagingCount = 3;
int totalPageCount = boardTotalCount/pagingCount;
boolean last = currentPage == totalPageCount? true : false;
request.setAttribute("first", first);
request.setAttribute("last", last);
return "index";
}
@GetMapping("/board/saveForm")
public String saveForm() {
return "board/saveForm";
}
@GetMapping("/board/1")
public String detail() {
return "board/detail";
}
}
{{> layout/header}}
<div class="container p-5">
{{#boardList}}
<div class="card mb-3">
<div class="card-body">
<h4 class="card-title mb-3">{{title}}</h4>
<a href="/board/{{id}}" class="btn btn-primary">상세보기</a>
</div>
</div>
{{/boardList}}
<ul class="pagination d-flex justify-content-center">
<li class="page-item"><a class="page-link" href="?page={{prevPage}}">Previous</a></li>
<li class="page-item"><a class="page-link" href="?page={{nextPage}}">Next</a></li>
</ul>
</div>
{{> layout/footer}}
Value Object : 값을 들고 있는 오브젝트
해당 값이 동일하면 동등한 것으로 간주
→ 상수 풀 같은 것을 만듦



Share article