본문 바로가기
MyBatis

[MyBatis] 동적쿼리 연습2 (복수 회원 탈퇴처리)

by moca7 2024. 10. 14.

 

 

 

ㅁ 테이블의 각 행의 맨 앞에 셀을 추가해서 체크박스 요소를 둔다.

 

 
<%@ 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 }/delete.me">
                <table border="1">
                    <thead>
                        <tr>
                            <th></th>
                            <th>번호</th>
                            <th>아이디</th>
                            <th>이름</th>
                            <th>주소</th>
                        </tr>
                    </thead>
                    <tbody>
                        <c:forEach var="m" items="${ list }">
                            <tr>
                                <td><input type="checkbox" name="delNo" value="${ m.userNo }"></td>
                                <td>${ m.userNo }</td>
                                <td>${ m.userId }</td>
                                <td>${ m.userName }</td>
                                <td>${ m.address }</td>
                            </tr>
                        </c:forEach>
                    </tbody>
                </table>

                <button type="submit">탈퇴</button>
            </form>
        </c:otherwise>
    </c:choose>

</body>
</html>
 

 

 

 

 

- 각 행은 list에서 m을 뽑아서 만들어져 있다. form으로 감싸서 요청시 checked된 각 행의 회원 번호를 넘긴다.

 

 

- 삭제 요청도 post로 한다. get방식은 주로 조회요청이다.

조회요청이 get방식, insert+update+delete는 post방식이라고 생각하면 된다.

 

- 그런데 조회여도 요청 데이터가 길거나, url에 데이터가 노출돼선 안되면 post로 한다.

 

 

 

 

 

 

ㅁ com.br.mybatis.member.controller에 MemberDeleteController 서블릿을만든다.

 

 
package com.br.mybatis.member.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.br.mybatis.member.service.MemberServiceImpl;

/**
 * Servlet implementation class MemberDeleteController
 */
@WebServlet("/delete.me")
public class MemberDeleteController extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public MemberDeleteController() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String[] deleteNo = request.getParameterValues("delNo"); // ["1", "13", "20"]
       
        int result = new MemberServiceImpl().deleteMember(deleteNo);
 
       
       
        if(result == deleteNo.length) {
            System.out.println("성공");
            response.sendRedirect(request.getContextPath());
        }else {
            System.out.println("실패");
        }
       
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}
 

 

 

 

 

 

ㅁ MemberService

 

 
package com.br.mybatis.member.service;

import java.util.List;
import java.util.Map;

import com.br.mybatis.member.dto.MemberDto;

public interface MemberService {

   
    // 인터페이스에서 public abstract를 붙이지 않아도 모든 메서드는 자동으로 추상 메서드로 취급됩니다.
   
   
    // 회원정보 상세조회
    MemberDto selectMember(int userNo);
   
    // 회원정보 변경
    int updateMember(MemberDto m);
   
    // 회원 검색
    List<MemberDto> selectSearchList(Map<String, Object> map);
   
    // 회원 탈퇴
    int deleteMember(String[] deleteNo);
}
 

 

 

 

 

 

ㅁ MemberServiceImpl

 

 
package com.br.mybatis.member.service;

import org.apache.ibatis.session.SqlSession;

import static com.br.mybatis.common.template.Template.*;

import java.util.List;
import java.util.Map;

import com.br.mybatis.member.dao.MemberDao;
import com.br.mybatis.member.dto.MemberDto;

public class MemberServiceImpl implements MemberService {

    private MemberDao memberDao = new MemberDao();
   
   
    @Override
    public MemberDto selectMember(int userNo) {
        SqlSession sqlSession = /*Template.*/getSqlSession();
        MemberDto m = memberDao.selectMember(sqlSession, userNo);
       
        sqlSession.close();
        return m;
    }

    @Override
    public int updateMember(MemberDto m) {
        SqlSession sqlSession = getSqlSession();
        int result = memberDao.updateMember(sqlSession, m);
       
        if(result > 0) {
            sqlSession.commit();
        }
       
        sqlSession.close();
        return result;
    }

    @Override
    public List<MemberDto> selectSearchList(Map<String, Object> map) {
        SqlSession sqlSession = getSqlSession();
        List<MemberDto> list = memberDao.selectSearchList(sqlSession, map);
       
        sqlSession.close();
        return list;
    }
   
    public int deleteMember(String[] deleteNo) {
        SqlSession sqlSession = getSqlSession();
        int result = memberDao.deleteMember(sqlSession, deleteNo);
       
        if(result == deleteNo.length) {
            sqlSession.commit();
        }
 
        sqlSession.close();
        return result;
    }

}
 

 

 

 

 

 

ㅁ MemberDao

 

 
package com.br.mybatis.member.dao;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import com.br.mybatis.member.dto.MemberDto;

public class MemberDao {

    public MemberDto selectMember(SqlSession sqlSession, int userNo) {
        return sqlSession.selectOne("memberMapper.selectMember", userNo);
    }

    public int updateMember(SqlSession sqlSession, MemberDto m) {
        return sqlSession.update("memberMapper.updateMember", m);
    }

    public List<MemberDto> selectSearchList(SqlSession sqlSession, Map<String, Object> map) {
        return sqlSession.selectList("memberMapper.selectSearchList", map);
    }

    public int deleteMember(SqlSession sqlSession, String[] deleteNo) {
        return sqlSession.update("memberMapper.deleteMember", deleteNo);
    }

}
 

 

- 회원탈퇴지만 delete를 하지 않고 update로 status 컬럼값만 바꾼다.

 

 

 

 

ㅁ member-mapper.xml

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

    <resultMap id="memberResultMap" type="MemberDto">
        <result column="user_no" property="userNo" />
        <result column="user_id" property="userId" />
        <result column="user_name" property="userName" />
        <result column="phone" property="phone" />
        <result column="email" property="email" />
        <result column="address" property="address" />
        <result column="interest" property="interest" typeHandler="StringArrTypeHandler"/>
    </resultMap>


    <select id="selectMember" resultMap="memberResultMap">
        select
                user_no
              , user_id
              , user_name
              , phone
              , email
              , address
              , interest
          from  member
         where  status in ('U', 'A')
           and  user_no = #{ userNo }          
    </select>


    <update id="updateMember">
        update
                member
           set  
                user_name = #{userName}    
              , phone = #{phone}    
              , email = #{email}
              , address = #{address}
              , interest = #{interest, typeHandler=StringArrTypeHandler}
         where user_no = #{userNo}    
    </update>


    <select id="selectSearchList" resultMap="memberResultMap">
        select
                user_no
              , user_id
              , user_name
              , address
          from  member
         where  status in ('U', 'A')    
         <choose>
            <when test="condition == 'no'">
                and user_no like '%' || #{keyword} || '%'
            </when>

            <when test='condition == "name"'>
            and user_name like '%' || #{keyword} || '%'
            </when>

            <otherwise>
            and user_id like '%${keyword}%'  
            </otherwise>
         </choose>
    </select>
   
   
    <update id="deleteMember">
        update
                member
           set  status = 'R'
        <where>
            <foreach item="no" collection="array"
                open="user_no in (" separator="," close=")">
                    #{no}
            </foreach>
        </where>        
    </update>

</mapper>
 

 

 

- memberMapper 파일의 deleteMember라는 id를 가지는 쿼리문을 작성한다.

 

- 넘겨받은 배열로부터 각각의 인덱스에 담겨있는 요소를 꺼내서 컴마 구분자와 함께 in의 괄호 안에 담아야 한다.

 

 

 

 

 

 

 

- 마이바티스에 마침 예시가 있다. 반복문을 돌릴 때는 foreach 태그다.

- 여기서 <where>~</where>을 복사해서 쿼리문에 붙여넣는다. 그리고 필요없는 속성들은 지운다. 

- <where> 태그는 조건절을 보다 간결하게 작성할 수 있도록 도와준다. 

조건이 없을 때는 WHERE 키워드를 자동으로 생략하고,

조건이 있을 때만 WHERE 키워드를 추가해준다. (값이 비어있지 않을 때만)

- 배열의 각 인덱스가 item에 담기고, item을 출력시킬 때는 #{ }으로 출력한다.

 

 

- 여기서의 collection은 자바의 List, Set, Map, 배열 등이 온다.

- collection에는 넘어온 파라미터에 대한 타입을 작성한다. 예시에서는 sql문으로 여러값이 담겨있는 list를 넘겼다.

배열을 넘긴다면 "list" 대신 "array"를 작성하면 된다.

- 각각의 인덱스에 담겨있는 값들이 순차적으로 접근한다.

 

- item은 변수명 역할이다. 순차적으로 접근된 값을 받는다. 변수명은 마음대로 지어도 된다.

- 순차적으로 접근할 때 인덱스도 필요하면 index 속성을 설정하면 된다.