참고 링크 : https://wikidocs.net/book/7601
오라클DB와 intelliJ로 작업하였습니다
앞서 Question 엔티티와 Answer 엔티티에 auther 속성을 추가했다. 게시판의 게시물에는 "글쓴이"를 표시하는 것이 일반적이다. 질문 목록, 질문 상세 화면에 auther 속성을 이용하여 글쓴이를 표시해 보자.
질문 목록
먼저 질문 목록 템플릿에 글쓴이를 표시해 보자. 다음과 같이 테이블 헤더에 글쓴이 항목을 추가하자.
question_list.html
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.w3.org/1999/xhtml"
layout:decorate="~{layout}">
<!--layout:decorate 속성 : 템플릿의 레이아웃(부모템플릿)으로 사용할 템플릿을 설정-->
<div layout:fragment="content" class="container my-3"> <!--<th:block layout:fragment="content"></th:block>-->
<table class="table">
<thead class="table-dark">
<tr class="text-center">
<th>번호</th>
<th style="width:50%">제목</th>
<th>글쓴이</th>
<th>작성일시</th>
</tr>
</thead>
<tbody>
<tr th:each="question, loop : ${paging}">
<td th:text="${paging.getTotalElements - (paging.number * paging.size) - loop.index}"></td>
<!--<td th:text="${loop.count}"></td>테이블항목에 번호추가-->
<td>
<a th:href="@{|/question/detail/${question.id}|}" th:text="${question.subject}"></a>
<!--해당질문에 달린답변개수 표시-->
<span class="text-danger small ms-2"
th:if="${#lists.size(question.answerList) > 0}"
th:text="${#lists.size(question.answerList)}"></span>
</td>
<!--날짜객체 날짜포맷에맞게 변환-->
<td th:text="${#dates.format(question.createDate, 'yyyy-MM-dd HH:mm')}"></td>
</tr>
</tbody>
</table>
<!-- 페이징처리 시작 -->
<div th:if="${!paging.isEmpty()}"><!--paging.isEmpty:페이지존재여부(게시물있으면 false,없으면 true)-->
<ul class="pagination justify-content-center">
<li class="page-item" th:classappend="${!paging.hasPrevious} ? 'disabled'">
<!-- !paging.hasPrevious - disabled : 이전페이지가 없으면 비활성화-->
<a class="page-link" th:href="@{|?page=${paging.number-1}|}">
<!--이전페이지 링크-->
<span>이전</span>
</a>
</li>
<!--th:each :페이지 리스트 루프--> <!--#numbers.sequence(시작, 끝)-->
<li th:each="page: ${#numbers.sequence(0, paging.totalPages-1)}"
th:if="${page >= paging.number-5 and page <= paging.number+5}"
th:classappend="${page == paging.number} ? 'active'"
class="page-item">
<!--page == paging.number : 현재페이지와 같으면 active 적용-->
<a th:text="${page}" class="page-link" th:href="@{|?page=${page}|}"></a>
</li>
<li class="page-item" th:classappend="${!paging.hasNext} ? 'disabled'">
<!-- !paging.hasNext - disabled : 다음페이지 없으면 비활성화-->
<a class="page-link" th:href="@{|?page=${paging.number+1}|}">
<!--다음페이지 링크-->
<span>다음</span>
</a>
</li>
</ul>
</div>
<!-- 페이징처리 끝 -->
<a th:href="@{/question/create}" class="btn btn-primary">질문 등록하기</a> <!--질문버튼추가 부트스트랩으로 버튼디자인!-->
</div>
</html>
<tr class="text-center">
<th>번호</th>
<th style="width:50%">제목</th>
<th>글쓴이</th>
<th>작성일시</th>
</tr>
<th>글쓴이</th> 항목을 추가했다.
그리고 th 엘리먼트를 가운데 정렬하도록 tr 태그에 text-center 클래스를 추가하고
제목의 너비가 전체에서 50%를 차지하도록 style="width:50%"도 지정해 주었다.
이어서 for 문에도 다음처럼 글쓴이를 적용하자.
question_list.html
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.w3.org/1999/xhtml"
layout:decorate="~{layout}">
<!--layout:decorate 속성 : 템플릿의 레이아웃(부모템플릿)으로 사용할 템플릿을 설정-->
<div layout:fragment="content" class="container my-3"> <!--<th:block layout:fragment="content"></th:block>-->
<table class="table">
<thead class="table-dark">
<tr class="text-center">
<th>번호</th>
<th style="width:50%">제목</th>
<th>글쓴이</th>
<th>작성일시</th>
</tr>
</thead>
<tbody>
<tr class="text-center" th:each="question, loop : ${paging}">
<td th:text="${paging.getTotalElements - (paging.number * paging.size) - loop.index}"></td>
<!--<td th:text="${loop.count}"></td>테이블항목에 번호추가-->
<td class="text-start">
<a th:href="@{|/question/detail/${question.id}|}" th:text="${question.subject}"></a>
<!--해당질문에 달린답변개수 표시-->
<span class="text-danger small ms-2"
th:if="${#lists.size(question.answerList) > 0}"
th:text="${#lists.size(question.answerList)}"></span>
</td>
<td>
<span th:if="${question.author != null}" th:text="${question.author.username}"></span>
</td>
<!--날짜객체 날짜포맷에맞게 변환-->
<td th:text="${#dates.format(question.createDate, 'yyyy-MM-dd HH:mm')}"></td>
</tr>
</tbody>
</table>
<!-- 페이징처리 시작 -->
<div th:if="${!paging.isEmpty()}"><!--paging.isEmpty:페이지존재여부(게시물있으면 false,없으면 true)-->
<ul class="pagination justify-content-center">
<li class="page-item" th:classappend="${!paging.hasPrevious} ? 'disabled'">
<!-- !paging.hasPrevious - disabled : 이전페이지가 없으면 비활성화-->
<a class="page-link" th:href="@{|?page=${paging.number-1}|}">
<!--이전페이지 링크-->
<span>이전</span>
</a>
</li>
<!--th:each :페이지 리스트 루프--> <!--#numbers.sequence(시작, 끝)-->
<li th:each="page: ${#numbers.sequence(0, paging.totalPages-1)}"
th:if="${page >= paging.number-5 and page <= paging.number+5}"
th:classappend="${page == paging.number} ? 'active'"
class="page-item">
<!--page == paging.number : 현재페이지와 같으면 active 적용-->
<a th:text="${page}" class="page-link" th:href="@{|?page=${page}|}"></a>
</li>
<li class="page-item" th:classappend="${!paging.hasNext} ? 'disabled'">
<!-- !paging.hasNext - disabled : 다음페이지 없으면 비활성화-->
<a class="page-link" th:href="@{|?page=${paging.number+1}|}">
<!--다음페이지 링크-->
<span>다음</span>
</a>
</li>
</ul>
</div>
<!-- 페이징처리 끝 -->
<a th:href="@{/question/create}" class="btn btn-primary">질문 등록하기</a> <!--질문버튼추가 부트스트랩으로 버튼디자인!-->
</div>
</html>
<td><span th:if="${question.author != null}" th:text="${question.author.username}"></span></td>
<td> ... </td> 엘리먼트를 삽입하여 질문의 글쓴이를 표시했다. 작성자 정보 없이 저장된 이전의 질문들은 author 속성에 해당하는 데이터가 없으므로 author 속성의 값이 null이 아닌 경우만 표시하도록 했다. 그리고 테이블 내용을 가운데 정렬하도록 tr 엘리먼트에 text-center 클래스를 추가하고, 제목을 왼쪽 정렬하도록 text-start 클래스를 추가했다.
질문 목록 화면에 글쓴이가 추가되었다. 변경된 질문 목록 화면은 다음 그림과 같다.
질문 상세
질문 상세 템플릿도 다음과 같이 글쓴이를 추가하자.
question_detail.html
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.w3.org/1999/xhtml"
layout:decorate="~{layout}">
<div layout:fragment="content" class="container my-3">
<!--질문-->
<h2 class="border-bottom py-2" th:text="${question.subject}"></h2>
<div class="card my-3">
<div class="card-body">
<div class="card-text" style="white-space: pre-line;" th:text="${question.content}"></div>
<div class="d-flex justify-content-end">
<div class="badge bg-light text-dark p-2 text-start">
<!--질문글쓴이-->
<div class="mb-2">
<span th:if="${question.author != null}" th:text="${question.author.username}"></span>
</div>
<div th:text="${#dates.format(question.createDate, 'yyyy-MM-dd HH:mm')}"></div>
</div>
</div>
</div>
</div>
<!--답변의 갯수표시-->
<h5 class="border-bottom my-3 py-2"
th:text="|${#lists.size(question.answerList)}개의 답변이 있습니다.|"></h5>
<!--#list.size(이터러블객체)-타임리프가 제공하는 유틸리티로 객체의 길이를 반환-->
<!--답변 반복 시작-->
<div class="card my-3" th:each="answer : ${question.answerList}">
<div class="card-body">
<div class="card-text" style="white-space: pre-line;" th:text="${answer.content}"></div>
<div class="d-flex justify-content-end">
<div class="badge bg-light text-dark p-2 text-start">
<div th:text="${#dates.format(answer.createDate, 'yyyy-MM-dd HH:mm')}"></div>
</div>
</div>
</div>
</div>
<!--답변 반복 끝-->
<!--답변 작성-->
<form th:action="@{|/answer/create/${question.id}|}"
th:object="${answerForm}" method="post" class="my-3">
<div th:replace="form_errors :: formErrorsFragment"></div>
<!--th:replace - 공통템플릿을 템플릿내에 삽입가능-->
<!--div엘리먼트를 form_errors.html파일의 th:fragment속성명이 formErrorsFragment인 엘리먼트로 교체-->
<textarea sec:authorize="isAnonymous()" disabled th:field="*{content}"
class="form-control" rows="10"></textarea>
<textarea sec:authorize="isAuthenticated()" th:field="*{content}"
class="form-control" rows="10"></textarea>
<input type="submit" value="답변등록" class="btn btn-primary my-2">
</form>
</div>
</html>
글쓴이와 작성일시가 함께 보이도록 수정했다.
<div class="mb-2"> <span th:if="${question.author != null}" th:text="${question.author.username}"></span> </div>
그리고 답변 부분도 글쓴이를 다음처럼 추가하자.
question_detail.html
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.w3.org/1999/xhtml"
layout:decorate="~{layout}">
<div layout:fragment="content" class="container my-3">
<!--질문-->
<h2 class="border-bottom py-2" th:text="${question.subject}"></h2>
<div class="card my-3">
<div class="card-body">
<div class="card-text" style="white-space: pre-line;" th:text="${question.content}"></div>
<div class="d-flex justify-content-end">
<div class="badge bg-light text-dark p-2 text-start">
<!--질문글쓴이-->
<div class="mb-2">
<span th:if="${question.author != null}" th:text="${question.author.username}"></span>
</div>
<div th:text="${#dates.format(question.createDate, 'yyyy-MM-dd HH:mm')}"></div>
</div>
</div>
</div>
</div>
<!--답변의 갯수표시-->
<h5 class="border-bottom my-3 py-2"
th:text="|${#lists.size(question.answerList)}개의 답변이 있습니다.|"></h5>
<!--#list.size(이터러블객체)-타임리프가 제공하는 유틸리티로 객체의 길이를 반환-->
<!--답변 반복 시작-->
<div class="card my-3" th:each="answer : ${question.answerList}">
<div class="card-body">
<div class="card-text" style="white-space: pre-line;" th:text="${answer.content}"></div>
<div class="d-flex justify-content-end">
<div class="badge bg-light text-dark p-2 text-start">
<!--답변글쓴이-->
<div class="mb-2">
<span th:if="${answer.author != null}" th:text="${answer.author.username}"></span>
</div>
<div th:text="${#dates.format(answer.createDate, 'yyyy-MM-dd HH:mm')}"></div>
</div>
</div>
</div>
</div>
<!--답변 반복 끝-->
<!--답변 작성-->
<form th:action="@{|/answer/create/${question.id}|}"
th:object="${answerForm}" method="post" class="my-3">
<div th:replace="form_errors :: formErrorsFragment"></div>
<!--th:replace - 공통템플릿을 템플릿내에 삽입가능-->
<!--div엘리먼트를 form_errors.html파일의 th:fragment속성명이 formErrorsFragment인 엘리먼트로 교체-->
<textarea sec:authorize="isAnonymous()" disabled th:field="*{content}"
class="form-control" rows="10"></textarea>
<textarea sec:authorize="isAuthenticated()" th:field="*{content}"
class="form-control" rows="10"></textarea>
<input type="submit" value="답변등록" class="btn btn-primary my-2">
</form>
</div>
</html>
마찬가지로 글쓴이와 작성일시가 함께 보이도록 수정했다.
변경된 질문 상세 화면은 다음과 같다.
'Follow Work > SpringbootBoard' 카테고리의 다른 글
[StringBoot] 추천 (24) (0) | 2022.08.17 |
---|---|
[StringBoot] 수정과 삭제 (23) (0) | 2022.08.17 |
[StringBoot] 엔티티 변경 (21) (0) | 2022.08.16 |
[StringBoot] 로그인과 로그아웃 (20) (0) | 2022.08.16 |
[StringBoot] 회원가입 (19) (0) | 2022.08.16 |