티스토리 뷰
1. HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax Test 5</title>
<link rel="stylesheet" th:href="@{/static/css/styles.css}">
<script th:src="@{/static/jq/jquery-3.7.1.min.js}"></script>
<script th:src="@{/static/js/test5JS.js}"></script>
</head>
<body>
<div class="container">
<header>
<h1>[ 임의의 게시판 ]</h1> <!-- 게시판 만들기 자체는 Web5 프로젝트 참고 -->
<p>게시판 내용</p>
<h1>[ Ajax Test 5 - 댓글 달기 ]</h1>
</header>
<main>
<div id="content" class="content">
<!-- AJAX 로드된 데이터가 아래에 표시됩니다. -->
<form id="inputForm">
<input type="text" id="name" name="name" placeholder="작성자명을 입력하세요.">
<input type="text" id="comment" name="comment" placeholder="댓글 내용을 입력하세요.">
<button type="button" id="inputButton">저장</button>
</form>
</div>
<hr>
<!-- 댓글 리스트 출력부분 -->
<table class="commentTable">
<thead>
<tr>
<th style="width: 8%">번호</th>
<th style="width: 16%">작성자</th>
<th style="width: 42%">내용</th>
<th style="width: 17%"></th>
<th style="width: 17%"></th>
</tr>
</thead>
<tbody id="commentTbody">
</tbody>
</table>
<!-- 모달 부분 -->
<div class="modalBack" id="modalBackground">
<div id="modalArea"></div>
</div>
</main>
<hr>
<form>
<a href="javascript:history.back();"><button type="button">HOME</button></a>
</form>
<footer>
<p>© 2024.08.14 AJAX Practice</p>
</footer>
</div>
</body>
</html>
2. Javascript
// ready 함수
$(document).ready(function () {
// 댓글 입력 버튼 클릭 시 commentInput 함수 실행
$('#inputButton').click(commentInput);
// 페이지 로딩 시 댓글 목록을 불러와 출력
list();
// 댓글 수정 버튼 클릭 이벤트 핸들러
$(document).on('click', '.editBtn', function () {
// 수정할 댓글의 고유 번호를 가져옴
let num = $(this).data('num');
console.log("수정 요청한 댓글 번호:{}", num);
// 사용자가 수정 버튼을 클릭하면, 모달 영역을 생성하여 수정 입력을 받음
let modal = `<div id="modal">
<span>${num}</span>번 글 수정하기<br>
내용 수정: <input id="reComment" type="text" style="width: 200px;margin-bottom: 10px"><br>
<button id="updateButton">수정</button></div>`;
// 모달 내용을 modalArea에 추가
$("#modalArea").html(modal);
// 모달과 배경 영역을 화면에 표시
$("#modalBackground").css("display", "block");
$("#modalArea").css("display", "block");
// 모달에서 수정 버튼 클릭 시 수정 처리
$(document).on('click', '#updateButton', function () {
// 수정할 데이터(댓글 번호, 이름, 내용)를 객체로 생성
let data = {num: num, name: $("#reName").val(), comment: $("#reComment").val()};
console.log("수정 요청한 정보: ", data);
// 수정 요청을 서버로 전송
$.ajax({
url: 'update',
type: 'post',
data: data,
success: function () {
alert('수정 완료');
// 수정 성공 시 댓글 목록 갱신
list();
// 모달과 배경 영역을 화면에서 숨김
$("#modalBackground").css("display", "none");
$("#modalArea").css("display", "none");
},
error: function () {
alert('수정 실패');
}
});
});
});
});
// 댓글 저장
function commentInput() {
// 이름 또는 댓글 내용이 비어있으면 경고 메시지 출력
if($('#name').val() == '' || $('#comment').val() == '') {
alert('이름 혹은 내용을 입력하세요.');
return;
}
// 댓글 저장 요청을 서버로 전송
$.ajax({
url : 'input',
type : 'post',
data : $('#inputForm').serialize(), // 폼 데이터를 직렬화하여 전송
success : function () {
alert('저장 성공');
// 저장 성공 시 입력 폼 초기화
$('#name').val('');
$('#comment').val('');
// 댓글 목록 갱신
list();
},
error : function () {
alert('저장 실패');
}
});
}
// 댓글 목록을 가져와서 출력
function list() {
// 댓글 목록을 가져오기 위한 GET 요청
$.ajax({
url: 'input', // 서버로부터 객체를 받을 URL
type: 'get', // HTTP 메서드 타입을 GET으로 설정
dataType: 'json', // 응답 데이터 타입을 JSON으로 설정
success: function (dtoList) {
console.log(dtoList);
$('#commentTbody').empty(); // 댓글 목록을 비워 초기화
// 각 댓글 데이터를 HTML로 변환하여 테이블에 추가
$(dtoList).each(function (index, item) {
let txt = `<tr>
<td>${item.num}</td>
<td>${item.name}</td>
<td>${item.comment}</td>
<td><button class="deleteBtn" data-num="${item.num}">삭제</button></td>
<td><button class="editBtn" data-num="${item.num}" data-name="${item.name}"
data-comment="${item.comment}">수정</button></td>
</tr>`;
$('#commentTbody').append(txt);
});
// 삭제 버튼 클릭 이벤트 핸들러 연결
$('.deleteBtn').click(deleteBtn);
// 수정 버튼 클릭 이벤트 핸들러 연결
$('.editBtn').click(editBtn);
},
error: function () {
alert('댓글 목록 불러오기 실패');
}
});
}
// 삭제 이벤트
function deleteBtn() {
// 삭제할 댓글의 고유 번호를 가져옴
let deleteNum = $(this).data('num');
// 댓글 삭제 요청을 서버로 전송
$.ajax({
url : 'delete',
type : 'post',
data : {num : deleteNum}, // 삭제할 댓글의 번호를 전송
success : function () {
alert('삭제 성공');
// 삭제 성공 시 댓글 목록 갱신
list();
},
error : function () {
alert('삭제 실패');
}
});
}
3. Controller
package net.datasa.test_ajax.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.datasa.test_ajax.domain.DTO.CommentDTO;
import net.datasa.test_ajax.service.AjaxTest5Service;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 댓글 관련 Ajax Controller
*/
@RestController // 이 클래스의 모든 메서드는 JSON 형태의 데이터를 반환하는 RESTful 웹 서비스의 엔드포인트로 동작함
@RequiredArgsConstructor // 필수 필드(final 필드)들을 포함한 생성자를 자동으로 생성
@Slf4j // 로깅 기능을 사용할 수 있도록 지원
@RequestMapping("comment") // 이 클래스의 모든 메서드는 "comment" 경로 하위의 URL에 매핑됨
public class AjaxTest5Controller {
// 서비스 객체 주입, 이 객체를 통해 비즈니스 로직을 처리
private final AjaxTest5Service ajaxTest5Service;
/**
* 댓글 저장을 처리하는 메서드
* @param commentDTO 저장할 댓글의 정보를 담고 있는 DTO 객체
*/
@PostMapping("input") // HTTP POST 요청을 처리하며, "comment/input" 경로와 매핑
public void input(CommentDTO commentDTO) {
// 전달된 DTO 객체를 로그에 출력하여 디버깅에 사용
log.debug("AjaxTest5Controller의 input() 메소드로 전달된 객체 : {}", commentDTO);
// DTO 객체를 서비스로 전달하여 데이터베이스에 저장
ajaxTest5Service.save(commentDTO);
}
/**
* 저장된 댓글 목록을 가져오는 메서드
* @return 댓글 DTO 리스트를 반환
*/
@GetMapping("input") // HTTP GET 요청을 처리하며, "comment/input" 경로와 매핑
public List<CommentDTO> getCommentDTO() {
// 서비스로부터 댓글 목록을 가져옴
List<CommentDTO> dtoList = ajaxTest5Service.list();
// 댓글 목록을 반환
return dtoList;
}
/**
* 댓글 삭제를 처리하는 메서드
* @param num 삭제할 댓글의 고유 번호
*/
@PostMapping("delete") // HTTP POST 요청을 처리하며, "comment/delete" 경로와 매핑
public void delete(Integer num) {
// 전달된 고유 번호를 로그에 출력하여 디버깅에 사용
log.debug("delete() 메소드로 전달된 객체 : {}", num);
// 고유 번호를 서비스로 전달하여 데이터베이스에서 해당 댓글을 삭제
ajaxTest5Service.delete(num);
}
/**
* 댓글 수정을 처리하는 메서드
* @param commentDTO 수정할 댓글의 정보를 담고 있는 DTO 객체
*/
@PostMapping("update") // HTTP POST 요청을 처리하며, "comment/update" 경로와 매핑
public void update(CommentDTO commentDTO) {
// 전달된 DTO 객체를 로그에 출력하여 디버깅에 사용
log.debug("update() 메소드로 전달된 객체 : {}", commentDTO);
// DTO 객체를 서비스로 전달하여 데이터베이스에서 해당 댓글을 수정
ajaxTest5Service.update(commentDTO);
}
}
4. Service
package net.datasa.test_ajax.service;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import net.datasa.test_ajax.domain.DTO.CommentDTO;
import net.datasa.test_ajax.domain.Entity.CommentEntity;
import net.datasa.test_ajax.repository.CommentRepository;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service // 이 클래스가 서비스 레이어의 컴포넌트임을 명시하며, 비즈니스 로직을 담당
@Transactional // 이 클래스 내의 메서드들이 트랜잭션 단위로 실행됨을 명시
@RequiredArgsConstructor // final로 선언된 필드들을 포함한 생성자를 자동으로 생성
public class AjaxTest5Service {
// 댓글 데이터를 처리하는 리포지토리 객체 주입
private final CommentRepository commentRepository;
/**
* 댓글 저장
* @param commentDTO 저장할 댓글 정보가 담긴 DTO 객체
*/
public void save(CommentDTO commentDTO) {
// DTO 객체를 엔티티 객체로 변환
CommentEntity commentEntity = new CommentEntity();
commentEntity.setName(commentDTO.getName());
commentEntity.setComment(commentDTO.getComment());
// 변환된 엔티티 객체를 데이터베이스에 저장
commentRepository.save(commentEntity);
}
/**
* 댓글 리스트 불러오기
* @return 모든 댓글 정보를 담고 있는 DTO 리스트 반환
*/
public List<CommentDTO> list() {
// 모든 댓글 엔티티를 데이터베이스에서 조회
List<CommentEntity> entityList = commentRepository.findAll();
// 조회된 엔티티를 DTO로 변환하여 담을 리스트 생성
List<CommentDTO> dtoList = new ArrayList<>();
// 엔티티 리스트를 순회하며 DTO로 변환
for (CommentEntity entity : entityList) {
CommentDTO commentDTO = new CommentDTO();
commentDTO.setNum(entity.getNum());
commentDTO.setName(entity.getName()); // 엔티티로부터 이름을 가져와 설정
commentDTO.setComment(entity.getComment()); // 엔티티로부터 댓글 내용을 가져와 설정
dtoList.add(commentDTO); // 변환된 DTO를 리스트에 추가
}
// 모든 댓글 정보를 포함한 DTO 리스트 반환
return dtoList;
}
/**
* 댓글 삭제
* @param num 삭제할 댓글의 고유 번호
*/
public void delete(Integer num) {
// 주어진 고유 번호를 가진 댓글을 데이터베이스에서 삭제
commentRepository.deleteById(num);
}
/**
* 댓글 수정
* @param commentDTO 수정할 댓글 정보가 담긴 DTO 객체
*/
public void update(CommentDTO commentDTO) {
// DTO 객체의 고유 번호로 엔티티를 조회, 없으면 예외 발생
CommentEntity commentEntity = commentRepository.findById(commentDTO.getNum())
.orElseThrow(() -> new RuntimeException("없는 댓글"));
// 조회된 엔티티의 댓글 내용을 DTO로부터 가져와 업데이트
commentEntity.setComment(commentDTO.getComment());
// 수정된 엔티티를 데이터베이스에 저장
commentRepository.save(commentEntity);
}
}
5. DTO
package net.datasa.test_ajax.domain.DTO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommentDTO {
private Integer num;
private String name;
private String comment;
}
6. Entity
package net.datasa.test_ajax.domain.Entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 댓글 엔티티
*/
@Data // Lombok 어노테이션으로, getter, setter, toString, equals, hashCode 메서드를 자동으로 생성
@Builder // Lombok 어노테이션으로, 빌더 패턴을 사용할 수 있게 합니다.
@NoArgsConstructor // Lombok 어노테이션으로, 매개변수가 없는 생성자를 자동으로 생성
@AllArgsConstructor // Lombok 어노테이션으로, 모든 필드를 매개변수로 가지는 생성자를 자동으로 생성
@Entity // JPA 어노테이션으로, 이 클래스가 엔티티임을 나타냄
@Table(name = "ajax_comment") // JPA 어노테이션으로, 엔티티와 매핑되는 테이블의 이름을 지정
public class CommentEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer num;
@Column(name="name", length = 30, nullable = false)
private String name;
@Column(name="comment",length = 1000, nullable = false)
private String comment;
}
7. Repository
package net.datasa.test_ajax.repository;
import net.datasa.test_ajax.domain.Entity.CommentEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CommentRepository extends JpaRepository<CommentEntity, Integer> {
}
'SCIT > 8월' 카테고리의 다른 글
8/19 [SpringBoot & JPA & Ajax Practice]家計簿(2) - ログイン (0) | 2024.08.19 |
---|---|
8/17 [SpringBoot & JPA & Ajax Practice]家計簿(1) - 会員登録 (0) | 2024.08.17 |
8/13 [Ajax] Test3. 추천 (0) | 2024.08.13 |
8/12 [Ajax] Test2. 서버로부터 객체 주고 받기 (0) | 2024.08.12 |
8/9 Spring Test. 성적 입력 (0) | 2024.08.12 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Spring
- Intellij idea
- ajax
- Linux
- Modal
- javascript
- springboot
- css
- data science academy
- Spring boot
- MySQL
- if문
- DB
- 가계부만들기
- setting
- java
- 반복문
- JPA
- 조건문
- html
- 2739번
- 오븐시계
- 백준
- backjoon
- 2480
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
글 보관함