[Spring] Todo 삭제 기능 만들기

민지·2024년 2월 6일
0

여태 만든 todo 기능은 add 기능밖에 없다. 그외의 추가기능으로 아래와 같이, delete 기능과 update 기능을 만들 것이다.

Todo 삭제 기능 만들기

현재 /list-todos 페이지 상황은 다음과 같다.

그런데, update 버튼을 add todo처럼 listTodos.jsp의 href="add-todo" 로 링크를 걸어 버튼처럼 만들 수 없다.

왜냐하면 add todo 버튼과는 달리, delete 버튼은 삭제될 단 1가지의 특정 todo행과 match되어야 하기 때문. 그래서 위 완성본 사진처럼, 모든 행에 delete버튼을 추가하면, 사용자는 특정 행에 대응되는 delete 버튼을 눌러, 특정 행의 todo만 지울 수 있게 된다.

다시 말해, 각각의 todo 바로 옆에 delete 버튼을 추가해야 한다.

1. 수정된 listTodos.jsp - 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를 삭제하려 한다고 알릴 수 있을까?

2. href URL에 쿼리 파라미터로 id값을 Controller 코드에 전송

// 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 버튼을 눌렀더니,

3. /delete-todo URL에 대응되는 컨트롤러 메서드 DeleteTodo()와 TodoService클래스에 DeleteById()메서드 만들기

TodoController클래스에 @RequestMapping으로 /delete-todo URL과 mapping되는 deleteTodo()메서드와 TodoService클래스에 todo를 삭제 기능을 하는 DeleteById()메서드를 만들자.

TodoService에 추가한 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를 삭제할 것!

TodoController클래스에 추가한 DeleteTodo()

// 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/

profile
배운 내용을 바로바로 기록하자!

0개의 댓글