08_Spring_240405(금)_59일차(0) - Spring Boot - todoList - 상세 조회, 수정, 삭제

soowagger·2024년 4월 5일

8_Spring

목록 보기
8/38

3. 할 일 상세 조회

TodoController

@GetMapping("detail")
public String todoDetail(@RequestParam("todoNo") int todoNo, Model model, RedirectAttributes ra) {
	
	Todo todo = service.todoDetail(todoNo);
	
	String path = null;
	
	if(todo != null) { // 조회 결과 있을 경우
		
		// forward : todo/detail
		path = "todo/detail";
		
		// request scope 값 세팅
		model.addAttribute("todo", todo);
		
		
	} else { // 조회 결과 없을 경우
		
		path = "redirect:/"; // 메인 페이지로 리다이렉트
		
		// RedirectAttributes :
		// - 리다이렉트 시 데이터를 request scope -> (잠시) session scope로
		//   전달할 수 있는 객체(응답 후 reqeust scope로 복귀)
		ra.addFlashAttribute("message", "해당 할 일이 존재하지 않습니다.");

	}
	
	return path;
	
}

TodoServiceImpl

// 할 일 상세 조회
@Override
public Todo todoDetail(int todoNo) {

	return mapper.todoDetail(todoNo);
}

todo-mapper.xml

<!-- 할 일 상세 조회 -->
<select id="todoDetail" parameterType="_int" resultType="Todo">
 	SELECT TODO_NO, TODO_TITLE, TODO_CONTENT, COMPLETE,
 	TO_CHAR(REG_DATE, 'YYYY-MM-DD HH24:MI:SS') REG_DATE
 	FROM TB_TODO
 	WHERE TODO_NO = ${todoNo}
</select>

detail.html

4. 완료 여부 수정

TodoController

/** 완료 여부 변경
 * @param todo : 커맨드 객체 (@ModelAttribute 생략)
 * 				- todoNo, complete 두 필드가 세팅된 상태
 * @return redirect:detail?todoNo=할 일 번호(상대경로)
 */
@GetMapping("changeComplete")
public String changeComplete(Todo todo, RedirectAttributes ra) {
	
	// 변경 서비스 호출
	int result = service.changeComplete(todo);
	
	// 변경 성공 시 : 변경 성공 메시지
	// 변경 실패 시 : 변공 실패 메시지
	
	String message = null;
	
	if(result > 0) message = "변경 성공!!";
	else message = "변경 실패..";
	
	// 현재 요청 주소 : /todo/changeComplete
	// 원하는 응답 주소 : /todo/detail
	ra.addFlashAttribute("message", message);
	
	return "redirect:detail?todoNo=" + todo.getTodoNo();
}
<!-- 완료 여부 변경 -->
<update id="changeComplete" parameterType="Todo">
 	UPDATE TB_TODO SET
 	COMPLETE = #{complete}
 	WHERE TODO_NO = ${todoNo}
</update>

detail.js

// 완료 여부 변경 버튼 동작
const completeBtn = document.querySelector(".complete-btn");

completeBtn.addEventListener("click", (e) => {
    
    const todoNo = e.target.dataset.todoNo;
    
    // Y <-> N 변경
    
    let complete = e.target.innerText; // 버튼 속성 중 th:text="${todo.complete}" -> 기존 완료 여부 값 얻어오기

    complete = (complete === 'Y') ? 'N' : 'Y';

    // 완료 여부 수정 요청하기
    location.href
        = `/todo/changeComplete?todoNo=${todoNo}&complete=${complete}`;
});

th:data-todo-no="${todo.todoNo}"
e.target.dataset.todoNo;

+ 목록으로 버튼

// 목록으로 버튼 동작
const goToList = document.querySelector("#goToList");

goToList.addEventListener("click", () => {
    location.href = "/"; // 메인 페이지 요청
});

5. 할 일 수정

TodoController

/** 수정 화면 전환
 * @return
 */
@GetMapping("update")
public String todoUpdate(@RequestParam("todoNo") int todoNo, Model model) {
	
	// 상세 조회 서비스 호출 -> 수정 화면에 출력할 이전 내용 
	Todo todo = service.todoDetail(todoNo);
	
	model.addAttribute("todo", todo);
	
	return "todo/update";
}


/** 할 일 수정
 * @param todo : 커맨드 객체(전달 받은 파라미터가 자동으로 DTO의 필드에 세팅된 객체 
 * @param ra
 * @return
 */
@PostMapping("update")
public String todoUpdate(Todo todo, RedirectAttributes ra) {
	
	// 수정 서비스 호출
	int result = service.todoUpdate(todo);
	
	String path = "redirect:";
	String message = null;
	
	if(result > 0) {
		// 상세 조회 페이지로 리다이렉트
		path += "/todo/detail?todoNo=" + todo.getTodoNo();
		message = "수정 성공!!";
		
	} else {
		
		path += "/todo/update?todoNo=" + todo.getTodoNo();
		message = "수정 실패..";
		
	}
	
	ra.addFlashAttribute("message", message);
	
	return path;
	
}

todo-mapper-xml

<!-- 할 일 수정 -->
<!-- 파라미터가 DTO인 경우 : #{필드명}, ${필드명} -->
<!-- 파마미터가 Map인 경우 : #{key}, ${key} -->
<update id="todoUpdate" parameterType="Todo">
 	UPDATE TB_TODO SET
 	TODO_TITLE = #{todoTitle},
 	TODO_CONTENT = #{todoContent}
 	WHERE TODO_NO = ${todoNo}
</update>

update.html

detail.js

// 수정 버튼 동작
const updateBtn = document.querySelector("#updateBtn");

updateBtn.addEventListener("click", e => {

    // data-todo-no 얻어오기
    const todoNo = e.target.dataset.todoNo;
    
    location.href = `/todo/update?todoNo=${todoNo}`;

});

6. 할 일 삭제

TodoController

/** 할 일 삭제
 * @param todoNo : 삭제할 할 일 번호
 * @param ra
 * @return 메인페이지 / 상세페이지
 */
@GetMapping("delete")
public String todoDelete(@RequestParam("todoNo") int todoNo, RedirectAttributes ra) {
	
	
	int result = service.todoDelete(todoNo);
	
	String path = null;
	String message = null;
	
	if(result > 0) { // 성공
		path = "/";
		message = "삭제 성공";
	} else { // 실패
		path = "/todo/detail?todoNo=" + todoNo;
		message = "삭제 실패";
	}
	
	ra.addFlashAttribute("message", message);
	
	return "redirect:" + path;
}

todo-mapper.xml

<!-- 할 일 삭제 -->
<delete id="todoDelete" parameterType="_int">
 	DELETE FROM TB_TODO
 	WHERE TODO_NO = ${todoNo}
</delete>

detail.js

// 삭제 버튼 동작
const deleteBtn = document.querySelector("#deleteBtn");

deleteBtn.addEventListener("click", e => {
      
    if(confirm("정말 삭제하시겠습니까?")) {
        location.href = `/todo/delete?todoNo=${e.target.dataset.todoNo}`;
    }
    
});

profile

0개의 댓글