1) SpringBoot
1-1) Server, JPA, DB 예제
1-1-1) 전체 회원 아이디 조회 후 아이디별 회원 상세 정보 조회
1-1-2) 각 아이디별 회원 정보 삭제
1-2) 추가 정리사항
1) SpringBoot
1-1) Server, JPA, DB 예제
[src/main/resources] - [templates] 안에 home.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>web3</title>
</head>
<body>
<h1>[ web3 ]</h1>
<p>
<a href="test">저장 테스트</a>
</p>
<p>
<a href="save">사용자 입력값을 저장</a>
</p>
<p>
<a href="select">사용자 정보 조회</a>
</p>
<p>
<a href="delete">사용자 정보 삭제</a>
</p>
<p>
<a href="selectAll">모든 회원 보기</a>
</p>
</body>
</html>
1-1-1) 전체 회원 아이디 조회 후 아이디별 회원 상세 정보 조회
(1) [src/main/resources] - [templates] 안에 selectAll.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 전체조회 결과</title>
<style>
div {
width: 100%
}
h1, table {
width: 600px;
margin: 0 auto;
text-align: center;
}
h1 {
padding-bottom: 50px;
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
font-weight: bold;
}
th, td {
width: 150px;
text-align: center;
}
th {
background-color: orange;
color: white;
}
th:nth-child(1) {
width: 50px
}
td:nth-child(1) {
width: 50px
}
</style>
</head>
<body>
<div>
<h1>[ 회원 전체조회 결과 ]</h1>
<table>
<tr>
<th>NO.</th>
<th>ID</th>
<th>ID2</th>
</tr>
<tr th:if="${personList == null or personList.isEmpty()}">
<td colspan="4">조회 결과가 없습니다.</td>
</tr>
<tr th:if="${personList}" th:each="person, num : ${personList}">
<td th:text="${num.count}"></td>
<td>
<a th:href="|view?id=${person.id}|" th:text="${person.id}"></a>
</td>
<td>
<a th:href="@{/info/{userid}(userid=${person.id})}" th:text="${person.id}"></a>
</td>
<!-- 경로 : /info/abc -->
</tr>
</table>
</div>
</body>
</html>
(2) [src/main/java] - [net.datasa.web3] 안에 PersonController.java 파일 생성 후 아래와 같이 작성
package net.datasa.web3;
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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
@Controller
public class PersonController {
private final PersonService personService;
@GetMapping("test")
public String test() {
personService.test();
return "redirect:/";
}
/**
* 입력 폼으로 이동
* @return Form이 있는 HTML 파일 경로
* */
@GetMapping("save")
public String save() {
return "inputForm";
}
/**
* form의 입력값을 받아서 저장
* */
@PostMapping("save")
public String save(@ModelAttribute PersonDTO dto) {
log.debug("전달된 값 : {}", dto);
personService.save(dto);
return "redirect:/";
}
/**
* 검색 form으로 이동
* @return HTML 파일 경로
* */
@GetMapping("select")
public String select() {
return "selectForm";
}
@PostMapping("select")
public String select(@RequestParam("id") String id, Model model) {
PersonDTO dto = personService.select(id);
model.addAttribute("id", id);
model.addAttribute("person", dto);
return "select";
}
// 삭제 form으로 이동
@GetMapping("delete")
public String delete() {
return "deleteForm";
}
// 삭제
@PostMapping("delete")
public String delete(@RequestParam("id") String id, Model model) {
boolean result = personService.delete(id);
// 삭제 여부와 삭제한 아이디를 모델에 저장하고 HTML로 포워딩
// 1. XXX : 없는 아이디입니다.
// 2. XXX 회원정보를 삭제했습니다.
model.addAttribute("id", id);
model.addAttribute("result", result);
return "delete";
}
// 모든 회원 보기
@GetMapping("selectAll")
public String selectAll(Model model) {
List<PersonDTO> dtoList = personService.selectAll();
// 리스트를 모델에 저장하고 selectAll.html로 포워딩
// 결과를 화면에 표 형태로 출력한다.
model.addAttribute("personList", dtoList);
return "selectAll";
}
// 1명의 회원 상세보기
@GetMapping("view")
public String view(@RequestParam("id") String id, Model model) {
PersonDTO dto = personService.select(id);
model.addAttribute("id", id);
model.addAttribute("person", dto);
return "select";
}
// 1명의 회원 상세보기(새로운 버전)
// 바로 위의 코드와 결과는 동일하지만 주소 보안성이 더 좋다(주소 상 노출되는 정보가 적어 사용자가 임의로 주소부분 값을 수정하여 페이지를 접속할 수 없다)
// 그래서 위의 방식보다 아래 방식을 더 추천함!
@GetMapping("/info" + "/{id}")
public String info(@PathVariable("id") String id, Model model) {
PersonDTO dto = personService.select(id);
model.addAttribute("id", id);
model.addAttribute("person", dto);
return "select";
}
}
(3) 결과 화면
첫 접속 화면
"모든 회원 보기" 문구 클릭 시 화면
"abc" 클릭 시 화면 (ID Column의 "abc" 클릭, ID2 Column의 "abc" 클릭 >> 주소값 비교해서 확인할 것)
1-1-2) 각 아이디별 회원 정보 삭제
(1) [src/main/resources] - [templates] 안에 selectAll.html 파일 생성 후 아래와 같이 작성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 전체조회 결과</title>
<style>
div {
width: 100%
}
h1, table {
width: 600px;
margin: 0 auto;
text-align: center;
}
h1 {
padding-bottom: 50px;
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
font-weight: bold;
}
th, td {
width: 150px;
text-align: center;
}
th {
background-color: orange;
color: white;
}
th:nth-child(1) {
width: 50px
}
td:nth-child(1) {
width: 50px
}
</style>
<!-- JQuery 파일을 불러온다. -->
<script src="/js/jquery-3.7.1.min.js"></script>
<script>
function del(id) {
if (confirm(id + " 회원 정보를 정말 삭제하시겠습니까?")) {
location.href = "deleteUser?id=" + id;
}
}
// ready 함수 안에서 삭제버튼(class가 delButton임)에 click 이벤트 처리
$(document).ready(function () {
$(".delButton").click(function() {
if (!confirm("삭제하시겠습니까?")) {
return;
}
// 이벤트가 발생한 버튼 객체의 data-id를 읽어옴
// let id1 = $(this).attr("data-id");
// ".data()"는 값을 미리 읽어오기 때문에 ".attr()"보다 속도 면에서 더 빠르다!
// ".data()"의 경우에는 어차피 "data"가 붙은 속성만 가져올 수 있기에
// 아래와 같이 "data-"를 생략한 "id" 값만으로 값을 가져올 수 있음!
let id2 = $(this).data("id");
// 삭제 경로로 요청
location.href = "deleteUser?id=" + id2;
});
});
</script>
</head>
<body>
<div>
<h1>[ 회원 전체조회 결과 ]</h1>
<table>
<tr>
<th>NO.</th>
<th>ID</th>
<th>ID2</th>
<th>삭제</th>
<th>삭제2</th>
<th>삭제3</th>
</tr>
<tr th:if="${personList == null or personList.isEmpty()}">
<td colspan="4">조회 결과가 없습니다.</td>
</tr>
<tr th:if="${personList}" th:each="person, num : ${personList}">
<td th:text="${num.count}"></td>
<td>
<a th:href="|view?id=${person.id}|" th:text="${person.id}"></a>
</td>
<td>
<a th:href="@{/info/{userid}(userid=${person.id})}" th:text="${person.id}"></a>
</td>
<!-- 경로 : /info/abc -->
<td>
<a th:href="|deleteUser?id=${person.id}|" th:text="${person.id}">삭제</a>
</td>
<!-- /deleteUser?id=abc -->
<td>
<button id="delBtn">
<a th:href="|javascript:del('${person.id}')|">삭제</a>
</button>
</td>
<!-- JQuery로 아래 버튼의 클릭 이벤트 처리하여 삭제 -->
<td>
<button class="delButton" th:data-id="${person.id}">삭제</button>
</td>
</tr>
</table>
</div>
</body>
</html>
(2) [src/main/java] - [net.datasa.web3] 안에 PersonController.java 파일 생성 후 아래와 같이 작성
package net.datasa.web3;
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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
@Controller
public class PersonController {
private final PersonService personService;
@GetMapping("test")
public String test() {
personService.test();
return "redirect:/";
}
/**
* 입력 폼으로 이동
* @return Form이 있는 HTML 파일 경로
* */
@GetMapping("save")
public String save() {
return "inputForm";
}
/**
* form의 입력값을 받아서 저장
* */
@PostMapping("save")
public String save(@ModelAttribute PersonDTO dto) {
log.debug("전달된 값 : {}", dto);
personService.save(dto);
return "redirect:/";
}
/**
* 검색 form으로 이동
* @return HTML 파일 경로
* */
@GetMapping("select")
public String select() {
return "selectForm";
}
@PostMapping("select")
public String select(@RequestParam("id") String id, Model model) {
PersonDTO dto = personService.select(id);
model.addAttribute("id", id);
model.addAttribute("person", dto);
return "select";
}
// 삭제 form으로 이동
@GetMapping("delete")
public String delete() {
return "deleteForm";
}
// 삭제
@PostMapping("delete")
public String delete(@RequestParam("id") String id, Model model) {
boolean result = personService.delete(id);
// 삭제 여부와 삭제한 아이디를 모델에 저장하고 HTML로 포워딩
// 1. XXX : 없는 아이디입니다.
// 2. XXX 회원정보를 삭제했습니다.
model.addAttribute("id", id);
model.addAttribute("result", result);
return "delete";
}
// 모든 회원 보기
@GetMapping("selectAll")
public String selectAll(Model model) {
List<PersonDTO> dtoList = personService.selectAll();
// 리스트를 모델에 저장하고 selectAll.html로 포워딩
// 결과를 화면에 표 형태로 출력한다.
model.addAttribute("personList", dtoList);
return "selectAll";
}
// 1명의 회원 상세보기
@GetMapping("view")
public String view(@RequestParam("id") String id, Model model) {
PersonDTO dto = personService.select(id);
model.addAttribute("id", id);
model.addAttribute("person", dto);
return "select";
}
// 1명의 회원 상세보기(새로운 버전)
// 바로 위의 코드와 결과는 동일하지만 주소 보안성이 더 좋다(주소 상 노출되는 정보가 적어 사용자가 임의로 주소부분 값을 수정하여 페이지를 접속할 수 없다)
// 그래서 위의 방식보다 아래 방식을 더 추천함!
@GetMapping("/info" + "/{id}")
public String info(@PathVariable("id") String id, Model model) {
PersonDTO dto = personService.select(id);
model.addAttribute("id", id);
model.addAttribute("person", dto);
return "select";
}
@GetMapping("deleteUser")
public String deleteUser(@RequestParam("id") String id) {
personService.delete(id);
return "redirect:selectAll";
}
}
(3) 결과 화면
첫 접속 화면
"모든 회원 보기" 문구 클릭 시 화면
삭제, 삭제2, 삭제3 내용 클릭 시 결과 화면 : ID가 "xyz"인 회원
(삭제 Column의 "abc" 클릭, 삭제2 Column의 "삭제" 버튼 클릭, 삭제3 Column의 "삭제" 버튼 클릭)
삭제2 Column의 "삭제" 버튼 클릭 시 Confirm 창 화면(확인 버튼 클릭 : 해당 회원 정보 삭제, 취소 버튼 클릭 : 삭제 취소)
삭제3 Column의 "삭제" 버튼 클릭 시 Confirm 창 화면(확인 버튼 클릭 : 해당 회원 정보 삭제, 취소 버튼 클릭 : 삭제 취소)
1-2) 추가 정리사항
// 경로가 http://localhost:8888/info/1/30일 경우
// 아래와 같은 형식으로 코드를 작성한다!
// @GetMapping("/info" + "/{a}" + "/{b}")
// public String info(@PathVariable("a") String a, @PathVariable("b") String b, Model model) {}
@GetMapping("/info" + "/{id}")
public String info(@PathVariable("id") String id, Model model) {
PersonDTO dto = personService.select(id);
model.addAttribute("id", id);
model.addAttribute("person", dto);
return "select";
}
"/{id}"와 @PathVariable("id")의 "id" 값이 반드시 서로 같아야 한다!
이 두 값은 html로부터 전달받은 데이터 값이라고 보면 된다.
Thymeleaf 형식("${~~}")을 사용할 경우에는 해당 속성명 앞에 반드시 "th:"를 붙여야 한다!
'SpringBoot' 카테고리의 다른 글
SpringBoot(17) - Server, JPA, DB 예제(테스트 저장, 방명록 쓰기) (0) | 2024.07.17 |
---|---|
SpringBoot(16) - Server, JPA, DB 예제(각 아이디별 회원 정보 수정), 추가 정리 사항 (0) | 2024.07.12 |
SpringBoot(14) - Server, JPA, DB 예제(특정 회원 정보 삭제 / 전체 회원 조회 결과 출력), 추가 정리 사항 (0) | 2024.07.10 |
SpringBoot(13) - Server, JPA, DB 예제(form 입력값 저장 / 검색 결과 출력), 추가 정리 사항 (0) | 2024.07.08 |
SpringBoot(12) - Spring Boot/JPA/MySQL 구조, 추가 정리 사항 (0) | 2024.07.05 |