템플릿은 자바 코드를 삽입할 수 있는 HTML 형식의 파일이며, 일반적으로 많이 사용하는 방식이다.
스프링부트에서 사용할수 있는 템플릿 엔진에는 Thymeleaf, Mustache, Groovy, Freemarker, Velocity 등이 있다.
✅ implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
추가
✅ implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect' spring.jpa.properties.hibernate.show_sql=true
추가
package com.mysite.sbb.question;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor // final이 붙은 속성을 포함하는 생성자 자동 생성
@Controller
public class QuestionController {
private final QuestionRepository questionRepository;
@GetMapping("/question/list") // 주소 매핑
public String list(Model model) {
List<Question> questionList = this.questionRepository.findAll();
// List타입의 questionList 인스턴스 생성
model.addAttribute("questionList", questionList);
// 모델이라는 객체에 주입 (String attributeName, Object attributeValue)
return "question_list"; // 템플릿 파일의 이름인 "question_list"를 리턴한다.
}
}
💬 스프링의 의존성 주입(Dependency Injection)방식
- @Autowired : 속성에 @Autowired 애너테이션을 적용하여 객체를 주입하는 방식
- 생성자 : 생성자를 작성하여 객체를 주입하는 방식 (권장하는 방식)
- Setter : Setter 메서드를 작성하여 객체를 주입하는 방식 (메서드에 @Autowired 애너테이션 적용이 필요하다.)
Model 객체는 자바 클래스와 템플릿 간의 연결고리 역할을 한다.
Model 객체에 "questionList" 라는 이름으로 questionList 값을 저장했다. Model 객체에 값을 담아두면 템플릿에서 그 값을 사용할 수 있다.
Model 객체는 따로 생성할 필요없이 컨트롤러 메서드의 매개변수로 지정하기만 하면 스프링부트가 자동으로 Model 객체를 생성한다.
<table>
<thead>
<tr>
<th>제목</th>
<th>작성일시</th>
</tr>
</thead>
<tbody>
<tr th:each="questionlist : ${questionList}">
<td th:text="${questionlist.subject}"></td>
<td th:text="${questionlist.createDate}"></td>
</tr>
</tbody>
</table>
템플릿 디렉토리 내부에 html파일을 생성한다!
<tr th:each="questionlist : ${questionList}">
<td th:text="${questionlist.subject}"></td>
<td th:text="${questionlist.createDate}"></td>
</tr>
th: 로 시작하는 속성은 타임리프 템플릿 엔진이 사용하는 속성이며 이 부분이 자바 코드와 연결된다.
QuestionController의 list 메서드에서 조회한 질문 목록 데이터를 "questionList"라는 이름으로 Model 객체에 저장했다. 타임리프는 Model 객체에 저장된 값을 읽을 수 있으므로 템플릿에서 questionList를 사용할수 있게 된다.
${} 괄호 안의 questionList는 Model이라는 객체에 저장되어 있다!
위의 코드는 <tr> ... </tr>
엘리먼트를 questionList의 갯수만큼 반복하여 출력하는 역할을 한다. 그리고 questionList에 저장된 데이터를 하나씩 꺼내 question 객체에 대입하여 반복구간 내에서 사용할수 있게 한다. 자바의 for each 문과 유사하다.
th:if="${question != null}"
question 객체가 null 이 아닌 경우에 해당 엘리먼트가 표시
반복문은 반복횟수만큼 해당 엘리먼트를 반복하여 표시한다. 반복문 속성은 자바의 for each 문과 유사하다.
th:each="question : ${questionList}"
반복문은 다음과 같이 사용할 수도 있다.
th:each="question, loop : ${questionList}"
추가한 loop 객체를 이용하여 루프 내에서 다음과 같은 속성을 사용할수 있다.
th:text=값 속성은 해당 엘리먼트의 텍스트로 "값"을 출력한다.
th:text="${question.subject}"
텍스트는 th:text 속성 대신에 다음처럼 대괄호를 사용하여 값을 직접 출력할수 있다.
<tr th:each="question : ${questionList}">
<td>[[${question.subject}]]</td>
<td>[[${question.createDate}]]</td>
</tr>