여태 만든 todo 기능은 add 기능밖에 없다. 그외의 추가기능으로 아래와 같이, delete 기능과 update 기능을 만들 것이다.
현재 /list-todos 페이지 상황은 다음과 같다.
그런데, update 버튼을 add todo처럼 listTodos.jsp의 href="add-todo" 로 링크를 걸어 버튼처럼 만들 수 없다.
왜냐하면 add todo 버튼과는 달리, delete 버튼은 삭제될 단 1가지의 특정 todo행과 match되어야 하기 때문. 그래서 위 완성본 사진처럼, 모든 행에 delete버튼을 추가하면, 사용자는 특정 행에 대응되는 delete 버튼을 눌러, 특정 행의 todo만 지울 수 있게 된다.
다시 말해, 각각의 todo 바로 옆에 delete 버튼을 추가해야 한다.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta charset="UTF-8">
<link href = "webjars/bootstrap/5.1.3/css/bootstrap.min.css" rel = "stylesheet">
<title>List Todos Page</title>
</head>
<body>
<div class = "container">
<h1>Your Todos</h1>
<table class = "table">
<thead>
<tr>
<th>id</th>
<th>Description</th>
<th>Deadline</th>
<th>is Done?</th>
<th>delete</th>
</tr>
</thead>
<tbody>
<c:forEach items = "${todos}" var = "todo">
<tr>
<td>${todo.id}</td>
<td>${todo.description}</td>
<td>${todo.deadline}</td>
<td>${todo.done}</td>
<td> <a href = "delete-todo" class = "btn btn-warning">Delete</a> <td>
</tr>
</c:forEach>
</tbody>
</table>
<a href = "add-todo" class = "btn btn-success">Add Todo</a>
<script src="webjars/bootstrap/5.1.3/js/bootstrap.min.js"></script>
<script src="webjars/jquery/3.6.0/jquery.min.js"></script>
</div>
</body>
</html>
listTodos.jsp에 Delete칸을 하나 더 만들고, 해당 칸 내용에는 <a href = "delete-todo">
태그를 통해, 클릭하면 /delete-todo URL로 이동하게 했다.
또한, add-todo 버튼과 달리, bootstrap css의 class로 btn-success가 아닌 btn-warning을 적용해 해당 버튼의 배경색상이 노란색으로 보이게끔 한다.
/list-todos URL의 실행결과는 다음과 같다.
delete 버튼은 추가됐다. 그렇다면 어떻게 id가 1번인 Todo를 삭제하려 한다고 알릴 수 있을까?
// listTodos.jsp 코드 일부분 : tbody 안에 a href의 쿼리파라미터 주목
<tbody>
<c:forEach items = "${todos}" var = "todo">
<tr>
<td>${todo.id}</td>
<td>${todo.description}</td>
<td>${todo.deadline}</td>
<td>${todo.done}</td>
<td> <a href = "delete-todo?id=${todo.id}" class = "btn btn-warning">Delete</a> <td>
</tr>
</c:forEach>
</tbody>
/list-todos 화면에서 id가 2인 todo의 delete 버튼을 눌렀더니,
/list-todos 화면에서 id가 3인 todo의 delete 버튼을 눌렀더니,
TodoController클래스에 @RequestMapping으로 /delete-todo URL과 mapping되는 deleteTodo()메서드와 TodoService클래스에 todo를 삭제 기능을 하는 DeleteById()메서드를 만들자.
public void DeleteById(int id) {
// 람다 함수 x -> y : todo -> todo.getId() == id
Predicate<? super Todo> predicate = todo -> todo.getId() == id;
todos.removeIf(predicate);
}
removeIf()메서드 정의 긁긁
함수 원형 : boolean removeIf(Predicate<? super Todo> filter)
해당 조건 (predicate)를 만족하는 collection의 모든 element 삭제!
predicate에 todo.getId() == id일 때, 로 조건 설정
함수형 프로그래밍, Lambdas and Functional Programming을 이용한 코드 (강의 말미에 java 프로그래밍 함수 코드 강의를 확인할 것!)
람다 함수 x -> y : todo -> todo.getId() == id
Todo에 있는 모든 Bean에 대해 해당 조건을 실행하게 된 것.
즉, 람다함수를 이용해 모든 Bean의 todo에 대해 id가 매칭되는지 확인하고, 매칭된다면 해당 todo case를 삭제할 것!
// delete-todo
@RequestMapping("/delete-todo")
public String deleteTodo(@RequestParam int id) {
// Delete todo
todoService.DeleteById(id);
// 삭제된 todo를 보여주는 redirect:list-todos
return "redirect:list-todos";
}
실행결과
id == 1인 행을 지웠더니, 삭제 후의 todo를 /list-todos에서 보여줬다.
이 시리즈는 Udemy 강의의 내용을 정리한 것입니다.
https://www.udemy.com/course/spring-boot-and-spring-framework-korean/