이렇게 생성 시간이 쓸데없는 정보까지 너무 세세하게 나와있어서 고쳐보려고한다.
형태를 변환하는데에 Jackson 라이브러리에서 제공하는 어노테이션인 @JsonFormat을 사용해보자
JSON 응답값의 형식을 지정할 때 사용한다.
응답값의 형식이란 날짜 형식 뿐만이 아니라 JSON 응답의 키 설정, 특정 값의 포함 여부, 응답값의 순서 등 여러가지 형태를 의미한다.
이 구문을 사용해서 적용시키려고 했지만 똑같이
이렇게 나와서 해결하지 못했다 이런 사소한 부분이 보기 안좋게 만들기때문에 나중에 꼭 해결하자!
이전에 게시글을 모달창으로 보여줬다면 비슷하게 댓글도 모달창으로 보여지게 설정하자
public User saveIdCheck(String newLoginId) {
User user = userRepository.findByLoginId(newLoginId).orElse(null);
return user;
}
기존의 코드는 db에서 똑같은 아이디값이 있다면 중복된 아이디라고 작성했다.
때문에 회원정보를 수정하기위해서는 무조건적으로 아이디의 변경이 필요했다.
이는 잘못되었다고 생각해서 수정 했다.
회원가입을 할때와 정보를 수정할때에 중복확인 서비스가 사용된다. 회원가입을 할때에는 기존에 로그인된 아이디 값이 없기때문에 위에 코드가 적용되도 문제가 없다. 때문에 중복을 확인 하는 서비스를 두개로 나눴다.
public User saveIdCheck(String newLoginId) {
User user = userRepository.findByLoginId(newLoginId).orElse(null);
return user;
}
public User modifyIdCheck(String newLoginId,@AuthenticationPrincipal PrincipalDetail principalDetail) {
String loginId = principalDetail.getUser().getLoginId();
if(loginId==newLoginId){
return null;
}
User user = userRepository.findByLoginId(newLoginId).orElse(null);
return user;
}
이어서 모달창을 완성해보자
모달창으로 댓글을 보여주기 위해서는 회원 목록에서 댓글의 수 를 클릭하면 그 댓글의 모든 정보를 보여줘야 한다. 이 모든 정보에는 댓글이 몇번째 글에 쓰여있는지도 포함이다
하지만 우리는 UserList에서 댓글의 정보를 빼와야하는데 이전에 설정했던 것처럼 replyDto에는 연관정보가 들어있지 않다 즉 userSelectDto를 통해서 replyDto 를 갖고올 수는 있지만 replyDto를 갖고 BoardDto를 가져올 수가 없었다.
때문에 다시 Dto를 수정한다.
(객체)Dto 의 이름을 갖는 dto들은 연관정보를 갖지 않지만 한개의 연관관계를 갖는, 예를 들어서 5번째 댓글은 1번의 글에 쓰여져있다 , 이것처럼 1 대 1 구조를 갖는 애들은 dto에 글 번호 userId 를 추가 시켜주었다.
(참고로 user는 boardList, replyList와 연관이기때문에 수정이 필요없다.)
package com.example.board_project.dto;
import com.example.board_project.entity.Board;
import com.example.board_project.entity.Reply;
import lombok.*;
import java.sql.Timestamp;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class ReplyDto { //오직 Reply의 정보만 갖고있다.
private int id;
private String content;
private int userId;
private int boardId;
private Timestamp createTime;
static public ReplyDto replyToReplyDto(Reply reply) {
ReplyDto replySelectDto = ReplyDto.builder()
.id(reply.getId())
.content(reply.getContent())
.userId(reply.getUser().getId())
.boardId(reply.getBoard().getId())
.createTime(reply.getCreateTime())
.build();
return replySelectDto;
}
}
package com.example.board_project.dto;
import com.example.board_project.entity.Board;
import com.example.board_project.entity.Reply;
import com.example.board_project.entity.User;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import java.sql.Timestamp;
import java.util.List;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class BoardDto { //오직 Board의 정보만 갖고있다.
private int id;
private String title;
private String content;
private int hit; //board 가 작성되는 순간 0 으로 설정
private int userId;
private Timestamp createTime;
static public BoardDto boardToBoardDto(Board board) {
BoardDto boardDto = BoardDto.builder()
.id(board.getId())
.title(board.getTitle())
.content(board.getContent())
.hit(board.getHit())
.userId(board.getUser().getId())
.createTime(board.getCreateTime())
.build();
return boardDto;
}
}
수정 했기 때문에 이제 모달에서 댓글이 몇번째 글에 쓰여있는지를 가져올수 있다.
admin.user.html 완성
<!DOCTYPE html>
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/default_layout}">
<div layout:fragment="content">
<!DOCTYPE html>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<div class="container mt-3">
<h2>회원 관리</h2>
<table class="table">
<thead>
<tr>
<th>회원 번호</th>
<th>아이디</th>
<th>닉네임</th>
<th>핸드폰번호</th>
<th>게시글 수</th>
<th>댓글 수</th>
<th>생성 시간</th>
</tr>
</thead>
<tr th:each="user:${userList}">
<td name="userId" th:text="${user.id}"></td>
<td th:text="${user.loginId}"></td>
<td th:text="${user.username}"></td>
<td th:text="${user.phoneNumber}"></td>
<td>
<button type="button" class="btn btn-link" name="showBoardModal"
th:text="${user.boardDtoList.size()}"></button>
</td>
<td>
<button type="button" class="btn btn-link" data-bs-toggle="modal" name="showReplyModal"
th:text="${user.replyDtoList.size()}"></button>
</td>
<td th:text="${user.createTime}"></td>
</tr>
</table>
</div>
<script th:inline="javascript">
$(document).ready(function () {
let closeBoardModalBtn = document.getElementById("boardModalClose");
let boardModal = document.getElementById("boardModal");
$("[name=showBoardModal]").click(function () {
let userId = $(this).parent().siblings("[name=userId]").text();
/*<![CDATA[*/
let userList = [[${userList}]];
/*]]*/
let boardModalHtml = "";
for (let i = 0; i < userList.length; i++) {
if (userList[i].id == userId) {
let boardList = userList[i].boardDtoList;
for (let i = 0; i < boardList.length; i++) {
boardModalHtml += "<tr>"
boardModalHtml += "<td>" + boardList[i].id + "</td>"
boardModalHtml += "<td>" + boardList[i].title + "</td>"
boardModalHtml += "<td>" + boardList[i].hit + "</td>"
boardModalHtml += "<td>" + userId + "</td>"
boardModalHtml += "<td>" + boardList[i].createTime + "</td>"
boardModalHtml += "</tr>"
}
break;
}
}
$("#boardModalBody").html(boardModalHtml);
$("#boardModal").show();
});
closeBoardModalBtn.onclick = function () {
boardModal.style.display = "none";
};
let closeReplyModalBtn = document.getElementById("replyModalClose");
let replyModal = document.getElementById("replyModal");
$("[name=showReplyModal]").click(function () {
let userId = $(this).parent().siblings("[name=userId]").text();
/*<![CDATA[*/
let userList = [[${userList}]];
/*]]*/
let replyModalHtml = "";
for (let i = 0; i < userList.length; i++) {
if (userList[i].id == userId) {
let replyList = userList[i].replyDtoList;
for (let i = 0; i < replyList.length; i++) {
replyModalHtml += "<tr>"
replyModalHtml += "<td>" + replyList[i].id + "</td>"
replyModalHtml += "<td>" + replyList[i].content + "</td>"
replyModalHtml += "<td>" + replyList[i].boardId + "</td>"
replyModalHtml += "<td>" + userId + "</td>"
replyModalHtml += "<td>" + replyList[i].createTime + "</td>"
replyModalHtml += "</tr>"
}
break;
}
}
$("#replyModalBody").html(replyModalHtml);
$("#replyModal").show();
});
closeReplyModalBtn.onclick = function () {
replyModal.style.display = "none";
};
});
</script>
<!-- 댓글 모달 부분-->
<div class="modal" id="boardModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">회원 관리</h4>
</div>
<!-- Modal body -->
<div>
<table class="table">
<thead>
<tr>
<th>게시글 번호</th>
<th>제목</th>
<th>조횟수</th>
<th>작성자 회원 번호</th>
<th>생성 시간</th>
</tr>
</thead>
<tbody id="boardModalBody">
</tbody>
</table>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button id="boardModalClose" type="button" class="btn btn-danger" data-bs-dismiss="modal">Close
</button>
</div>
</div>
</div>
</div>
<!-- 댓글 모달 부분-->
<div class="modal" id="replyModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">회원 관리</h4>
</div>
<!-- Modal body -->
<div>
<table class="table">
<thead>
<tr>
<th>댓글 번호</th>
<th>내용</th>
<th>해당 게시글</th>
<th>작성자 회원 번호</th>
<th>생성 시간</th>
</tr>
</thead>
<tbody id="replyModalBody">
</tbody>
</table>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button id="replyModalClose" type="button" class="btn btn-danger" data-bs-dismiss="modal">Close
</button>
</div>
</div>
</div>
</div>
</div>
</html>