1) SpringBoot
1-1) Server, JPA, DB 예제
1-1-1) 글 목록
1-1-2) 글 삭제
1-1-3) 글 수정
1) SpringBoot
1-1) Server, JPA, DB 예제
[src/main/resources] - [templates] 안에 home.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>web4</title>
</head>
<body>
<h1>[ web4 ]</h1>
<p>
<a href="list">방명록</a>
</p>
</body>
</html>
[src/main/java] - [net.datasa.web4.domain.dto] 안에 GuestBookDTO.java 파일 생성 후 아래와 같이 작성
package net.datasa.web4.domain.dto;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class GuestBookDTO {
Integer num; // 글 번호(기본키)
String name; // 작성자 이름
String password; // 비밀번호
String message; // 게시글 내용
LocalDateTime inputdate; //작성시간
}
1-1-1) 글 목록
(1) [src/main/java] - [net.datasa.web4.controller] 안에 GuestBookController.java 파일 생성 후 아래와 같이 작성
package net.datasa.web4.controller;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.datasa.web4.domain.dto.GuestBookDTO;
import net.datasa.web4.service.GuestBookService;
@Slf4j
@RequiredArgsConstructor
@Controller
public class GuestBookController {
// @RequiredArgsConstructor : Lombok 라이브러리에서 제공하는 Annotation으로,
// 해당 Annotation이 적용된 필드를 기반으로 생성자를 자동 생성해주는 역할을 한다.
// (객체 변수에 final 키워드를 붙여 값이 변경되지 않도록 만듦)
// 따라서 GuestBookController 클래스는 "@RequiredArgsConstructor" Annotation을 통해
// 생성자를 만들어 주기 때문에 아래의 service 객체 정의 코드만으로 생성자를 실행시켜 서비스 객체를 자동으로 생성해줌!
private final GuestBookService guestbookService;
/*
* public class GuestBookController {
* GuestBookController(GuestBookService guestbookService) {
* this.guestbookService = guestbookService;
* }
* }
*/
// home.html에서 "test" 경로 클릭하면 처리할 메소드 정의
// GuestBookService의 test() 메서드 호출하여 entity 생성하여 DB에 저장
// 실행 후 메인화면으로 다시 redirect
@GetMapping("test")
public String test() {
guestbookService.test();
return "redirect:/";
}
// home 화면에서 "글쓰기"를 클릭하면 입력 form으로 이동
@GetMapping("write")
public String write() {
return "writeForm";
}
// 입력 form에서 글쓰고 "저장" 버튼 누르면 받아서 글 저장
@PostMapping("write")
public String write(@ModelAttribute GuestBookDTO dto) {
log.debug("전달된 값 : {}", dto);
guestbookService.writeSave(dto);
return "redirect:/";
}
// 글 목록
@GetMapping("list")
public String list(Model model) {
List<GuestBookDTO> dtoList = guestbookService.list();
log.debug("전달된 값 : {}", dtoList);
model.addAttribute("list", dtoList);
// forwarding(포워딩) : 정보를 유지하면서 이동하는 것을 말함
// redirect : 지금까지의 정보를 다 버리고 새로 시작하겠다는 것을 의미함
// list.html 페이지로 포워딩하는 코드이다!
return "list";
}
}
(2) [src/main/java] - [net.datasa.web4.service] 안에 GuestBookService.java 파일 생성 후 아래와 같이 작성
package net.datasa.web4.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import jakarta.persistence.EntityNotFoundException;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import net.datasa.web4.domain.dto.GuestBookDTO;
import net.datasa.web4.domain.entity.GuestBookEntity;
import net.datasa.web4.repository.GuestBookRepository;
@RequiredArgsConstructor
@Service
@Transactional
public class GuestBookService {
private final GuestBookRepository guestbookRepository;
// 저장 테스트
public void test() {
// GuestBookEntity entity = new GuestBookEntity(1, "aaa", "111", "글 내용1", null);
GuestBookEntity entity = GuestBookEntity.builder()
.name("aaa")
.password("111")
.message("글 내용1")
.build();
guestbookRepository.save(entity);
}
/**
* 글 저장
* @param dto 저장할 글 내용
* */
public void writeSave(GuestBookDTO dto) {
GuestBookEntity entity = GuestBookEntity.builder()
.name(dto.getName())
.password(dto.getPassword())
.message(dto.getMessage())
.build();
guestbookRepository.save(entity);
}
// select * from guestbook order by num desc; SQL 문과 동일한 기능을 수행한다!
public List<GuestBookDTO> list() {
// 만약 정렬 조건이 여러 개인 경우
// Sort sort = Sort.by(
// Sort.Order.desc("inputdate"),
// Sort.Order.desc("num"),
// Sort.Order.asc("name")
//);
// Sort : SQL의 order by 구문을 만들어주는 역할
Sort sort = Sort.by(Sort.Direction.DESC, "num");
List<GuestBookEntity> entityList = guestbookRepository.findAll(sort);
List<GuestBookDTO> dtoList = new ArrayList<>();
// 반복문으로 Entity 객체를 DTO로 변환해서 ArrayList에 저장
for (GuestBookEntity entity : entityList) {
GuestBookDTO dto = GuestBookDTO.builder()
.num(entity.getNum())
.name(entity.getName())
.message(entity.getMessage())
.inputdate(entity.getInputdate())
.build();
dtoList.add(dto);
}
return dtoList;
}
}
(3) [src/main/resources] - [templates] 안에 list.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>방명록</title>
<style>
#layout {
width: 500px;
margin: 0 auto;
}
h1 {
text-align: center;
}
th {
display: inline-block;
width: 70px;
text-align: left;
}
textarea {
width: 350px;
height: 70px;
}
</style>
</head>
<body>
<div id="layout">
<h1>[ 방명록 ]</h1>
<p>
<a href="write">글쓰기</a>
</p>
<!-- 글목록 출력 영역 -->
<table th:each="list, n : ${list}">
<hr>
<tr>
<th>번호: </th>
<td th:text="${list.num}"></td>
</tr>
<tr>
<th>작성자: </th>
<td th:text="${list.name}"></td>
</tr>
<tr>
<th>작성일: </th>
<td th:text="${#temporals.format(list.inputdate, 'yy년 MM월 dd일 HH시 mm분 ss초')}"></td>
</tr>
<tr>
<td colspan="2"><textarea th:text="${list.message}"></textarea></td>
</tr>
<tr>
<td colspan="2">
<form th:action="@{/delete}" method="post">
<input type="hidden" name="num" th:value="${list.num}">
<label>비밀번호</label>
<input type="text" name="password" required>
<input type="submit" value="삭제">
</form>
</td>
</tr>
</table>
</div>
</body>
</html>
(4) 결과 화면
글 목록(list.html) 화면
1-1-2) 글 삭제
(1) [src/main/java] - [net.datasa.web4.controller] 안에 GuestBookController.java 파일 생성 후 아래와 같이 작성
package net.datasa.web4.controller;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.datasa.web4.domain.dto.GuestBookDTO;
import net.datasa.web4.service.GuestBookService;
@Slf4j
@RequiredArgsConstructor
@Controller
public class GuestBookController {
// @RequiredArgsConstructor : Lombok 라이브러리에서 제공하는 Annotation으로,
// 해당 Annotation이 적용된 필드를 기반으로 생성자를 자동 생성해주는 역할을 한다.
// (객체 변수에 final 키워드를 붙여 값이 변경되지 않도록 만듦)
// 따라서 GuestBookController 클래스는 "@RequiredArgsConstructor" Annotation을 통해
// 생성자를 만들어 주기 때문에 아래의 service 객체 정의 코드만으로 생성자를 실행시켜 서비스 객체를 자동으로 생성해줌!
private final GuestBookService guestbookService;
/*
* public class GuestBookController {
* GuestBookController(GuestBookService guestbookService) {
* this.guestbookService = guestbookService;
* }
* }
*/
// home.html에서 "test" 경로 클릭하면 처리할 메소드 정의
// GuestBookService의 test() 메서드 호출하여 entity 생성하여 DB에 저장
// 실행 후 메인화면으로 다시 redirect
@GetMapping("test")
public String test() {
guestbookService.test();
return "redirect:/";
}
// home 화면에서 "글쓰기"를 클릭하면 입력 form으로 이동
@GetMapping("write")
public String write() {
return "writeForm";
}
// 입력 form에서 글쓰고 "저장" 버튼 누르면 받아서 글 저장
@PostMapping("write")
public String write(@ModelAttribute GuestBookDTO dto) {
log.debug("전달된 값 : {}", dto);
guestbookService.writeSave(dto);
return "redirect:/";
}
// 글 목록
@GetMapping("list")
public String list(Model model) {
List<GuestBookDTO> dtoList = guestbookService.list();
log.debug("전달된 값 : {}", dtoList);
model.addAttribute("list", dtoList);
// forwarding(포워딩) : 정보를 유지하면서 이동하는 것을 말함
// redirect : 지금까지의 정보를 다 버리고 새로 시작하겠다는 것을 의미함
// list.html 페이지로 포워딩하는 코드이다!
return "list";
}
// 글 삭제
@PostMapping("delete")
public String delete(
@RequestParam("num") Integer num,
@RequestParam("password") String password,
RedirectAttributes redirectAttributes) {
try {
guestbookService.delete(num, password);
}
catch (Exception e) {
e.printStackTrace();
redirectAttributes.addFlashAttribute("msg", "게시글 삭제 실패");
}
return "redirect:list";
}
}
(2) [src/main/java] - [net.datasa.web4.service] 안에 GuestBookService.java 파일 생성 후 아래와 같이 작성
package net.datasa.web4.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import jakarta.persistence.EntityNotFoundException;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import net.datasa.web4.domain.dto.GuestBookDTO;
import net.datasa.web4.domain.entity.GuestBookEntity;
import net.datasa.web4.repository.GuestBookRepository;
@RequiredArgsConstructor
@Service
@Transactional
public class GuestBookService {
private final GuestBookRepository guestbookRepository;
// 저장 테스트
public void test() {
// GuestBookEntity entity = new GuestBookEntity(1, "aaa", "111", "글 내용1", null);
GuestBookEntity entity = GuestBookEntity.builder()
.name("aaa")
.password("111")
.message("글 내용1")
.build();
guestbookRepository.save(entity);
}
/**
* 글 저장
* @param dto 저장할 글 내용
* */
public void writeSave(GuestBookDTO dto) {
GuestBookEntity entity = GuestBookEntity.builder()
.name(dto.getName())
.password(dto.getPassword())
.message(dto.getMessage())
.build();
guestbookRepository.save(entity);
}
// select * from guestbook order by num desc; SQL 문과 동일한 기능을 수행한다!
public List<GuestBookDTO> list() {
// 만약 정렬 조건이 여러 개인 경우
// Sort sort = Sort.by(
// Sort.Order.desc("inputdate"),
// Sort.Order.desc("num"),
// Sort.Order.asc("name")
//);
// Sort : SQL의 order by 구문을 만들어주는 역할
Sort sort = Sort.by(Sort.Direction.DESC, "num");
List<GuestBookEntity> entityList = guestbookRepository.findAll(sort);
List<GuestBookDTO> dtoList = new ArrayList<>();
// 반복문으로 Entity 객체를 DTO로 변환해서 ArrayList에 저장
for (GuestBookEntity entity : entityList) {
GuestBookDTO dto = GuestBookDTO.builder()
.num(entity.getNum())
.name(entity.getName())
.message(entity.getMessage())
.inputdate(entity.getInputdate())
.build();
dtoList.add(dto);
}
return dtoList;
}
public void delete(Integer num, String password) {
// 해당 번호의 글 조회
// 없으면 예외발생
GuestBookEntity entity = guestbookRepository.findById(num)
.orElseThrow(() -> new EntityNotFoundException("게시글이 없습니다."));
// 비밀번호 비교
// 틀리면 예외발생
if (!password.equals(entity.getPassword())) {
throw new RuntimeException("비밀번호가 틀립니다.");
}
// 맞으면 삭제
guestbookRepository.delete(entity);
}
}
(3) [src/main/resources] - [templates] 안에 list.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>방명록</title>
<style>
#layout {
width: 500px;
margin: 0 auto;
}
h1 {
text-align: center;
}
th {
display: inline-block;
width: 70px;
text-align: left;
}
textarea {
width: 350px;
height: 70px;
}
</style>
<script th:src="@{/js/jquery-3.7.1.min.js}"></script>
<script>
$(document).ready(function() {
if ("[[${msg}]]") {
alert("[[${msg}]]");
}
});
</script>
</head>
<body>
<div id="layout">
<h1>[ 방명록 ]</h1>
<p>
<a href="write">글쓰기</a>
</p>
<!-- 글목록 출력 영역 -->
<table th:each="list, n : ${list}">
<hr>
<tr>
<th>번호: </th>
<td th:text="${list.num}"></td>
</tr>
<tr>
<th>작성자: </th>
<td th:text="${list.name}"></td>
</tr>
<tr>
<th>작성일: </th>
<td th:text="${#temporals.format(list.inputdate, 'yy년 MM월 dd일 HH시 mm분 ss초')}"></td>
</tr>
<tr>
<td colspan="2"><textarea th:text="${list.message}"></textarea></td>
</tr>
<tr>
<td colspan="2">
<form th:action="@{/delete}" method="post">
<input type="hidden" name="num" th:value="${list.num}">
<label>비밀번호</label>
<input type="text" name="password" required>
<input type="submit" value="삭제">
</form>
</td>
</tr>
</table>
</div>
</body>
</html>
(4) 결과 화면
"삭제" 버튼 클릭 전후 화면 : "삭제" 버튼을 클릭하면 브라우저 화면과 DB에서 해당 글이 완전히 삭제됨!
클릭 전 화면
클릭 후 화면
1-1-3) 글 수정
(1) [src/main/java] - [net.datasa.web4.controller] 안에 GuestBookController.java 파일 생성 후 아래와 같이 작성
package net.datasa.web4.controller;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.datasa.web4.domain.dto.GuestBookDTO;
import net.datasa.web4.service.GuestBookService;
@Slf4j
@RequiredArgsConstructor
@Controller
public class GuestBookController {
// @RequiredArgsConstructor : Lombok 라이브러리에서 제공하는 Annotation으로,
// 해당 Annotation이 적용된 필드를 기반으로 생성자를 자동 생성해주는 역할을 한다.
// (객체 변수에 final 키워드를 붙여 값이 변경되지 않도록 만듦)
// 따라서 GuestBookController 클래스는 "@RequiredArgsConstructor" Annotation을 통해
// 생성자를 만들어 주기 때문에 아래의 service 객체 정의 코드만으로 생성자를 실행시켜 서비스 객체를 자동으로 생성해줌!
private final GuestBookService guestbookService;
/*
* public class GuestBookController {
* GuestBookController(GuestBookService guestbookService) {
* this.guestbookService = guestbookService;
* }
* }
*/
// home.html에서 "test" 경로 클릭하면 처리할 메소드 정의
// GuestBookService의 test() 메서드 호출하여 entity 생성하여 DB에 저장
// 실행 후 메인화면으로 다시 redirect
@GetMapping("test")
public String test() {
guestbookService.test();
return "redirect:/";
}
// home 화면에서 "글쓰기"를 클릭하면 입력 form으로 이동
@GetMapping("write")
public String write() {
return "writeForm";
}
// 입력 form에서 글쓰고 "저장" 버튼 누르면 받아서 글 저장
@PostMapping("write")
public String write(@ModelAttribute GuestBookDTO dto) {
log.debug("전달된 값 : {}", dto);
guestbookService.writeSave(dto);
return "redirect:/";
}
// 글 목록
@GetMapping("list")
public String list(Model model) {
List<GuestBookDTO> dtoList = guestbookService.list();
log.debug("전달된 값 : {}", dtoList);
model.addAttribute("list", dtoList);
// forwarding(포워딩) : 정보를 유지하면서 이동하는 것을 말함
// redirect : 지금까지의 정보를 다 버리고 새로 시작하겠다는 것을 의미함
// list.html 페이지로 포워딩하는 코드이다!
return "list";
}
// 글 삭제
@PostMapping("delete")
public String delete(
@RequestParam("num") Integer num,
@RequestParam("password") String password,
RedirectAttributes redirectAttributes) {
try {
guestbookService.delete(num, password);
}
catch (Exception e) {
e.printStackTrace();
redirectAttributes.addFlashAttribute("msg", "게시글 삭제 실패");
}
return "redirect:list";
}
// 글 수정
@PostMapping("update")
public String update(
@RequestParam("num") Integer num,
Model model
) {
GuestBookDTO dto = guestbookService.select(num);
model.addAttribute("writing", dto);
return "updateWriting";
}
// update form에서 글 내용 수정하고 "수정" 버튼 누르면 받아서 수정된 글 저장
@PostMapping("updateSave")
public String update(
@ModelAttribute GuestBookDTO dto,
RedirectAttributes redirectAttributes) {
log.debug("전달된 값 : {}", dto);
try {
guestbookService.updateSave(dto);
}
catch (Exception e) {
e.printStackTrace();
redirectAttributes.addFlashAttribute("msg", "게시글 수정 실패");
}
return "redirect:list";
}
}
(2) [src/main/java] - [net.datasa.web4.service] 안에 GuestBookService.java 파일 생성 후 아래와 같이 작성
package net.datasa.web4.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import jakarta.persistence.EntityNotFoundException;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import net.datasa.web4.domain.dto.GuestBookDTO;
import net.datasa.web4.domain.entity.GuestBookEntity;
import net.datasa.web4.repository.GuestBookRepository;
@RequiredArgsConstructor
@Service
@Transactional
public class GuestBookService {
private final GuestBookRepository guestbookRepository;
// 저장 테스트
public void test() {
// GuestBookEntity entity = new GuestBookEntity(1, "aaa", "111", "글 내용1", null);
GuestBookEntity entity = GuestBookEntity.builder()
.name("aaa")
.password("111")
.message("글 내용1")
.build();
guestbookRepository.save(entity);
}
/**
* 글 저장
* @param dto 저장할 글 내용
* */
public void writeSave(GuestBookDTO dto) {
GuestBookEntity entity = GuestBookEntity.builder()
.name(dto.getName())
.password(dto.getPassword())
.message(dto.getMessage())
.build();
guestbookRepository.save(entity);
}
// select * from guestbook order by num desc; SQL 문과 동일한 기능을 수행한다!
public List<GuestBookDTO> list() {
// 만약 정렬 조건이 여러 개인 경우
// Sort sort = Sort.by(
// Sort.Order.desc("inputdate"),
// Sort.Order.desc("num"),
// Sort.Order.asc("name")
//);
// Sort : SQL의 order by 구문을 만들어주는 역할
Sort sort = Sort.by(Sort.Direction.DESC, "num");
List<GuestBookEntity> entityList = guestbookRepository.findAll(sort);
List<GuestBookDTO> dtoList = new ArrayList<>();
// 반복문으로 Entity 객체를 DTO로 변환해서 ArrayList에 저장
for (GuestBookEntity entity : entityList) {
GuestBookDTO dto = GuestBookDTO.builder()
.num(entity.getNum())
.name(entity.getName())
.message(entity.getMessage())
.inputdate(entity.getInputdate())
.build();
dtoList.add(dto);
}
return dtoList;
}
public void delete(Integer num, String password) throws Exception {
// 해당 번호의 글 조회
// 없으면 예외발생
GuestBookEntity entity = guestbookRepository.findById(num)
.orElseThrow(() -> new EntityNotFoundException("게시글이 없습니다."));
// 비밀번호 비교
// 틀리면 예외발생
if (!password.equals(entity.getPassword())) {
throw new RuntimeException("비밀번호가 틀립니다.");
}
// 맞으면 삭제
guestbookRepository.delete(entity);
}
public GuestBookDTO select(Integer num) {
// findById() : Primary Key 기준으로 검색을 하는 메서드
// orElse(null) : 결과가 없으면 "null" 값을 대입하는 메서드
GuestBookEntity entity = guestbookRepository.findById(num).orElse(null);
if (entity == null) {
return null;
}
GuestBookDTO dto = new GuestBookDTO();
dto.setNum(entity.getNum());
dto.setName(entity.getName());
dto.setPassword(entity.getPassword());
dto.setMessage(entity.getMessage());
dto.setInputdate(entity.getInputdate());
return dto;
}
public void updateSave(GuestBookDTO dto) throws Exception {
// DB의 정보를 조회
GuestBookEntity entity = guestbookRepository.findById(dto.getNum())
.orElseThrow(() -> new EntityNotFoundException("게시글이 없습니다."));
// 비밀번호 비교
// 틀리면 예외발생
if (!dto.getPassword().equals(entity.getPassword())) {
throw new RuntimeException("비밀번호가 틀립니다.");
}
// 값 수정
entity.setMessage(dto.getMessage());
// 저장
guestbookRepository.save(entity);
}
}
(3) [src/main/resources] - [templates] 안에 list.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>방명록</title>
<style>
#layout {
width: 500px;
margin: 0 auto;
}
h1 {
text-align: center;
}
th {
display: inline-block;
width: 70px;
text-align: left;
}
textarea {
width: 350px;
height: 70px;
}
</style>
<script th:src="@{/js/jquery-3.7.1.min.js}"></script>
<script>
$(document).ready(function() {
if ("[[${msg}]]") {
alert("[[${msg}]]");
}
});
</script>
</head>
<body>
<div id="layout">
<h1>[ 방명록 ]</h1>
<p>
<a href="write">글쓰기</a>
</p>
<!-- 글목록 출력 영역 -->
<table th:each="list, n : ${list}">
<hr>
<tr>
<th>번호: </th>
<td th:text="${list.num}"></td>
</tr>
<tr>
<th>작성자: </th>
<td th:text="${list.name}"></td>
</tr>
<tr>
<th>작성일: </th>
<td th:text="${#temporals.format(list.inputdate, 'yy년 MM월 dd일 HH시 mm분 ss초')}"></td>
</tr>
<tr>
<td colspan="2"><textarea th:text="${list.message}"></textarea></td>
</tr>
<tr>
<td colspan="2">
<form th:action="@{/delete}" method="post">
<input type="hidden" name="num" th:value="${list.num}">
<label>비밀번호</label>
<input type="text" name="password" required>
<input type="submit" value="삭제">
</form>
</td>
</tr>
<tr>
<td colspan="2">
<form th:action="@{/update}" method="post">
<input type="hidden" name="num" th:value="${list.num}">
<input type="hidden" name="message" th:value="${list.message}">
<input type="submit" value="수정">
</form>
</td>
</tr>
</table>
</div>
</body>
</html>
(4) [src/main/resources] - [templates] 안에 updateWriting.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>방명록 글 수정</title>
</head>
<body>
<h1>[ 방명록 글 수정 ]</h1>
<br>
<form th:action="@{/updateSave}" method="post">
<table>
<tr>
<td>
<input type="hidden" name="num" th:value="${writing.num}">
</td>
</tr>
<tr>
<th>내용</th>
<td>
<textarea name="message" id="message" th:text="${writing.message}"></textarea>
</td>
</tr>
<tr>
<td colspan="2">
<input type="hidden" name="num" th:value="${writing.num}">
<label>비밀번호</label>
<input type="text" name="password" required>
<input type="submit" value="수정" id="updateBtn">
</td>
</tr>
</table>
</form>
</body>
</html>
(5) 결과 화면
"수정" 버튼 클릭 전후 화면 : "수정" 버튼을 클릭하여 글 수정 페이지로 이동한 후 비밀번호를 올바르게 입력하고 글 내용을 수정하면 방명록 리스트 화면과 DB에서 해당 글 내용이 모두 수정됨!
클릭 전 화면
클릭 후 화면
'SpringBoot' 카테고리의 다른 글
SpringBoot(20) - Security 예제(Thymeleaf), 복습 예제(회원가입) (0) | 2024.07.23 |
---|---|
SpringBoot(19) - Security 예제(로그인, 로그아웃) (0) | 2024.07.22 |
SpringBoot(17) - Server, JPA, DB 예제(테스트 저장, 방명록 쓰기) (0) | 2024.07.17 |
SpringBoot(16) - Server, JPA, DB 예제(각 아이디별 회원 정보 수정), 추가 정리 사항 (0) | 2024.07.12 |
SpringBoot(15) - Server, JPA, DB 예제(전체 회원 아이디 조회 후 아이디별 회원 상세 정보 조회 / 각 아이디별 회원 정보 삭제), 추가 정리 사항 (0) | 2024.07.11 |