본문 바로가기
Spring

[Spring] MyBatis(8) 게시글 일괄삭제

by moca7 2024. 10. 22.

 

 

 

ㅁ list.jsp

 

 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

  <h3>공지사항 목록 페이지</h3>

  <c:choose>
    <c:when test="${ empty list }">
      존재하는 공지사항이 없습니다
    </c:when>
   
    <c:otherwise>
      <form action="${ contextPath }/notice/delete.do" method="post">
        <table border="1">
          <thead>
            <tr>
              <th></th>
              <th>번호</th>
              <th>제목</th>
              <th>내용</th>
            </tr>
          </thead>
         
          <tbody>
            <c:forEach var="n" items="${ list }">
              <tr>
                <td><input type="checkbox" name="deleteNo" value="${ n.no }"></td>
                <td>${ n.no }</td>
                <td><a href="${contextPath}/notice/detail.do?no=${n.no}">${ n.title }</a></td>
                <td>${ n.content }</td>
              </tr>
            </c:forEach>
          </tbody>
        </table>
       
        <button type="submit">삭제</button>
      </form>
    </c:otherwise>
  </c:choose>


  <a href="${contextPath}/notice/enroll.do">공지사항 등록</a>

</body>
</html>
 

 

- <c:otherwise> 안의 table 요소를 form으로 감싸고 삭제 버튼을 두었다.

- 각 행에 맨 처음에 셀을 추가하고 type이 checkbox인 input 요소를 두었다.

- name속성을 줘서 deleteNo이라는 key값으로 다수의 값들이 넘어갈 수 있다.

 

 

 

 

 

ㅁ NoticeController

 

 
package com.br.sbatis.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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.br.sbatis.dto.NoticeDto;
import com.br.sbatis.service.NoticeService;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequestMapping("/notice")
@RequiredArgsConstructor
@Controller
public class NoticeController {

 
  private final NoticeService noticeService;
 
  @GetMapping("/list.do") // /notice/list.do
  public void noticeList(Model model) {
    List<NoticeDto> list = noticeService.selectNoticeList();
    log.debug("list: {}", list);
    model.addAttribute("list", list);
   
    // return "notice/list"; void여도 포워딩하려 한다. url mapping("/notice/list")를 가지고 포워딩한다.
  }
 
 
 
  @GetMapping("/detail.do") // /notice/detail.do
  public void noticeDetail(int no, Model model) {
    NoticeDto n = noticeService.selectNoticeByNo(no);
    model.addAttribute("n",n);
  }
 
 
  @GetMapping("/enroll.do") // /notice/enroll.do
  public void noticeEnroll() {}
  // 이렇게만 작성해도 페이지 이동이 된다.
 
 
  @PostMapping("/insert.do")
  public String noticeInsert(NoticeDto n) {
    int result = noticeService.insertNotice(n);
   
    if(result > 0) { // 성공시 다시 목록페이지
      return "redirect:/notice/list.do";
    }else { // 실패시 메인페이지
      return "redirect:/";
    }
  }
 
 
 
  @GetMapping("/modify.do") // /notice/modify.do
  public void noticeModify(int no, Model model) {
    model.addAttribute("n", noticeService.selectNoticeByNo(no));
  }
 
 
  @PostMapping("/update.do")
  public String noticeUpdate(NoticeDto n) {
    int result = noticeService.updateNotice(n);

    if(result > 0){ // 성공시 상세페이지
      return "redirect:/notice/detail.do?no=" + n.getNo();
    }else { // 실패시 목록페이지
      return "redirect:/notice/list.do";
    }
  }
 
  @PostMapping("/delete.do")
  public String noticeDelete(String[] deleteNo) {
    // String[] arr = request.getParameterValues("deleteNo") <- request 객체가 있었다면
   

      // 체크박스 선택 안 한 경우 예외 처리
      if (deleteNo == null || deleteNo.length == 0) {
          // 선택 항목이 없을 경우 에러 메시지와 함께 목록 페이지로 이동
          return "redirect:/notice/list.do?error=noSelection";
      }
   
   
   
    // 실행할 sql문 : delete from notice where no in (xx, xx, xx) <- 동적 쿼리
   
    int result = noticeService.deleteNotice(deleteNo);
   
    if(result == deleteNo.length){ // 성공시 목록페이지
      return "redirect:/notice/list.do";
    }else { // 실패시 메인페이지
      return "redirect:/";
    }
  }

}

 

- noticeDelete 메소드 작성.

 

- error=noSelection은 임의로 만든 파라미터다. 

이를 통해 JSP 페이지에서 특정 상황에 맞는 경고 메시지를 출력할 수 있도록 한 예시입니다.

 

 

 

 

 

ㅁ NoticeServiceImpl

 

 
package com.br.sbatis.service;

import java.util.List;

import org.springframework.stereotype.Service;

import com.br.sbatis.dao.NoticeDao;
import com.br.sbatis.dto.NoticeDto;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
public class NoticeServiceImpl implements NoticeService {
 
 
  private final NoticeDao noticeDao;
 

  @Override
  public List<NoticeDto> selectNoticeList() {
    return noticeDao.selectNoticeList();
  }

  @Override
  public NoticeDto selectNoticeByNo(int noticeNo) {
    return noticeDao.selectNoticeByNo(noticeNo);
  }

  @Override
  public int insertNotice(NoticeDto n) {
    return noticeDao.insertNotice(n);
  }

  @Override
  public int updateNotice(NoticeDto n) {
    return noticeDao.updateNotice(n);
  }

  @Override
  public int deleteNotice(String[] deleteNo) {
    return noticeDao.deleteNotice(deleteNo);
  }
 
 

}

 

- deleteNotice 메소드 작성.

 

 

 

 

ㅁ NoticeDao

 

 
package com.br.sbatis.dao;

import java.util.List;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Repository;

import com.br.sbatis.dto.NoticeDto;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Repository
public class NoticeDao {
 
  private final SqlSessionTemplate sqlSession;
 
 
  public List<NoticeDto> selectNoticeList() {
    return sqlSession.selectList("noticeMapper.selectNoticeList");
  }
 
  public NoticeDto selectNoticeByNo(int noticeNo) {
    return sqlSession.selectOne("noticeMapper.selectNoticeByNo", noticeNo);
  }
 
  public int insertNotice(NoticeDto n) {
    return sqlSession.insert("noticeMapper.insertNotice", n);
  }
 
  public int updateNotice(NoticeDto n) {
    return sqlSession.update("noticeMapper.updateNotice", n);
  }

  public int deleteNotice(String[] deleteNo) {
    return sqlSession.delete("noticeMapper.deleteNotice", deleteNo);
  }
 
}

 

- deleteNotice 메소드 작성.

 

 

 

 

ㅁ notice-mapper.xml

 

 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<mapper namespace="noticeMapper">


  <resultMap id="noticeResultMap" type="NoticeDto">
    <result column="no" property="no" />
    <result column="title" property="title" />
    <result column="content" property="content" />
  </resultMap>


 
  <select id="selectNoticeList" resultMap="noticeResultMap">
    select
           no
        ,  title
        ,  content
      from notice
     order
        by no desc      
  </select>
 
 
 
  <!-- 번호로 공지사항 조회 -->
  <select id="selectNoticeByNo" resultMap="noticeResultMap">
    select
            no
         ,  title
         ,  content
      from  notice
     where  no = #{ noticeNo }
  </select>
 
 
  <!-- 공지사항 등록 -->
  <insert id="insertNotice">
    insert
      into notice
      (
        no
      , title
      , content    
      )
      values
      (
        seq_notice.nextval
      , #{ title }
      , #{ content }  
      )
  </insert>
 
 
  <!-- 공지사항 수정 -->
  <update id="updateNotice">
    update
            notice
       set  title = #{title}
         ,  content = #{content}      
     where  no = #{no}          
  </update>
 
 
  <!-- 공지사항 삭제 (동적 쿼리) -->
  <delete id="deleteNotice">
    delete
      from
            notice
   <where>
     <foreach item="no" collection="array"
         open="no in (" separator="," close=")">
             #{no}
     </foreach>      
   </where>
  </delete>

 
 
 
</mapper>

 

 

- 공지사항 삭제 쿼리를 작성한다. 

- 참고 : 마이바티스 동적쿼리(https://moca7.tistory.com/264)