프로젝트명 : Dwp_Ch12_JDBC_Bean_MultiDel (삭제 - 선택,전체선택)


데이터를 delete하기 위해서는 먼저 데이터를 가지고 오는 것 부터.
select 페이지에서 선택항목 삭제 버튼을 누르면 페이지 이동을 하도록 구성한다.
아래와 같다.
btn_Del(항목삭제 버튼)에 id가 아닌 class가 속성으로 들어간 이유는
for 구문으로 버튼도 계속 돌리면서 생성되기 때문에
여러개가 생성가능한 class 속성으로 설정하는 것이다.
for 구문 바깥쪽에 있는 multiDel(선택항목삭제 버튼)은 그래서 id 지정이 가능했다.
<%@page import="pack_Bean.SVO"%>
<%@page import="java.util.List"%>
<%@page import="java.sql.SQLException"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" autoFlush="true" %>
<jsp:useBean id="objDAO" class="pack_Bean.DAO" scope="page" />
<%
List<SVO> objList = objDAO.mtd_Select();
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>회원목록</title>
<link rel="shortcut icon" href="#">
<link rel="stylesheet" href="/style/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="/script/script.js"></script>
</head>
<body>
<div id="wrap" class="selectWrap">
<h1>회원목록 페이지(SVO 적용)</h1>
<hr>
<table id="memListTBL">
<tbody>
<tr>
<th>
<input type="checkbox" id="chkAll">
선택
<!-- 전체 선택을 하는 체크 박스 -->
</th>
<th>번호</th>
<th>아이디</th>
<th>비밀번호</th>
<th>나이</th>
<th>성별</th>
<th>가입시간</th>
<th>삭제</th>
</tr>
<% for (int i=0; i<objList.size(); i++) {
SVO objSVO = objList.get(i);
String gender = "M";
if (objSVO.getGender() == 2) gender = "F";
%>
<tr>
<td>
<input type="checkbox" form="memDelForm"
name="num" class="memDelChk" value="<%=objSVO.getNum()%>">
<!-- memDelChk의 여러개 클래스는 num이라는 이름을 가지며
가지고 있는 value값인 num값을 form으로 memDelForm 에게 전달한다
-->
</td>
<td><%=objSVO.getNum() %></td>
<td><%=objSVO.getUid() %></td>
<td><%=objSVO.getUpw() %></td>
<td><%=objSVO.getuAge() %></td>
<td><%=gender %></td>
<td>
<%=objSVO.getJoinTM() %>
</td>
<td>
<button class="btn_Del"
value="<%=objSVO.getNum()%>">
×
</button>
<!-- 버튼 btn_Del도 num값을 가지고 있지만
form요소를 사용하지 않고 바로 js에서 작업한다 -->
</td>
</tr>
<% } %>
</tbody>
<tfoot>
<tr>
<td colspan="6"> </td>
<td colspan="2">
<button type="button" id="multiDel">선택항목삭제</button>
<!-- 선택항목을 삭제하는 버튼을 tfoot에서 생성한다. -->
<button type="button" onclick="location.href='/index.jsp'">
Main
</button>
</td>
</tr>
</tfoot>
</table>
<!-- table#memListTBL -->
<form id="memDelForm"></form>
<!-- form요소로 전달하는 기능 -->
</div>
<!-- div#wrap -->
</body>
</html>

데이터를 여러개 이동시키는 것이 아니라
DB에서 가지고 있는 데이터 중 중복이 안되는 것만 골라
delete 페이지로 이동하는 것이므로
form요소 말고 onclick="자바스크립트"를 사용한다.
이때 넘겨주는 데이터는 unique key, primary key여야 한다.
왜냐하면, 중복되는 값이 삭제되어 버리면 여러명의 정보가 사라질 수 있기 때문이다.
번호를 나타나는 num , 중복값을 가질 수 없는 아이디 값을 delete 페이지로 넘기면 되겠다.
js 파일.
$(function(){
////////////// 회원 목록 페이지 개별 삭제 시작 //////////////
$("button.btn_Del").click(function(){
let procChk = confirm("해당 회원목록을 삭제하시겠습니까?");
if (procChk) {
let param = $(this).val();
location.href = "/delete/deleteProc.jsp?num="+param;
} else {
alert("취소하셨습니다.");
}
});
////////////// 회원 목록 페이지 개별 삭제 끝 //////////////
////////////// 회원 목록 삭제 대상 선택 체크박스 시작 //////////////
/////// 체크박스 전체 선택/해제 시작
$("input#chkAll").click(function(){
let chkToF = $(this).prop("checked");
//console.log("chkToF : " + chkToF);
$("input.memDelChk").prop("checked", chkToF);
});
/////// 체크박스 전체 선택/해제 끝
/////// 회원 다중 삭제 시작
// 유효성 검사
$("button#multiDel").click(function(){
let chkCnt = 0; // 체크박스 체크 상태 개수
let len = $("input.memDelChk").length; // 회원 목록에 표시되는 체크박스 개수
for (let i=0; i<len; i++) {
let chkToF = $("input.memDelChk").eq(i).prop("checked");
if(chkToF) chkCnt++;
}
if(chkCnt == 0) {
alert("삭제하실 아이디를 선택하세요.");
} else {
let procChk = confirm("해당 회원목록을 삭제하시겠습니까?");
if (procChk) {
$("form#memDelForm")
.attr("action", "/delete/deleteMultiProc.jsp")
.submit();
} else {
alert("취소하셨습니다.");
}
}
});
/////// 회원 다중 삭제 끝
////////////// 회원 목록 삭제 대상 선택 체크박스 끝 //////////////
});
deleteProc.jsp
deleteMultiProc.jsp
두 delete 파일 모두
jsp:useBean을 사용하여 objDAO의 값을 받는 다는 것을 알수 있다.
그건 알겠는데,
int num = Integer.parseInt(request.getParameter("num")); 과
String[] num = request.getParameterValues("num"); 이것들은 무엇일까?
바로 DAO로 들어가는 매개변수! 그러면 DAO에 위치하고 있는 각각의 메서드들이
인수로 받아서 반환 해줄 것이다. 그것이 바로 int rtnCnt 뒤에 위치하는
objDAO.mtd_Del(num); 과 objDAO.mtd_MultiDel(num); 값이다

rtnCnt는 DB에 저장된 row갯수의 값이라고 보면 된다. 개별적으로 가진 버튼을 선택하면 당연히 한개의 값만이 반환되어 rtnCnt == 1
이 나오겠지만,
오른쪽의 deleteMultiProc를 보면 선택한 만큼 rtnCnt가 증가하므로 0보다 클 경우로 조건문을 생성하게 된다.
DAO.java 파일
갖가지의 메서드들로 가득하다.
나도 이렇게 멋지게 코드를 짜고 싶지만.. 아직은 강사님 코드 따라 쓰기 바쁨
import는 java.sql.* 이렇게 해도 먹는다.
DAO 클래스에서
Connection,PreparedStatement,Statement,ResultSet은 계속 쓰이기 때문에 바깥으로 빼서 모든 메서드에서
사용할 수 있도록 했다.
package pack_Bean;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Vector;
public class DAO {
Connection objConn = null;
PreparedStatement objPstmt = null;
Statement objStmt = null;
ResultSet objRS = null;
private List<SVO> objList = null;
// 데이터 입력 시작
public int mtd_Insert(VO objVO) {
int rtnCnt = 0;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/Dwp_Ch12_JDBC_Bean?";
url += "useSSL=false&";
url += "useUnicode=true&";
url += "characterEncoding=UTF8&";
url += "serverTimezone=UTC";
String user = "root";
String password = "1234";
objConn = DriverManager.getConnection(url, user, password);
//out.print("DB 접속 OK!!!");
/* 매개변수가 있는 SQL 시작 */
String sql1 = "insert into member (uid, upw, uAge, gender, joinTM)";
sql1 += " values (?, ?, ?, ?, now())";
objPstmt = objConn.prepareStatement(sql1);
objPstmt.setString(1, objVO.getUid()); // 문자자료형 C/N1
objPstmt.setString(2, objVO.getUpw()); // 문자자료형 C/N1
objPstmt.setInt(3, objVO.getuAge()); // 문자자료형 C/N1
objPstmt.setInt(4, objVO.getGender()); // 정수자료형 C/N2
rtnCnt = objPstmt.executeUpdate();
/* 매개변수가 있는 SQL 끝 */
objPstmt.close();
objConn.close(); // GC, Garbage Collector, 가비지 컬렉터,
// 메모리 자료 정리기
} catch (ClassNotFoundException cnfe) {
System.out.println(cnfe.getMessage());
} catch (SQLException sqle) {
System.out.println(sqle.getMessage());
}
return rtnCnt;
}
// 데이터 입력 끝
// 데이터 조회(=회원 목록 출력) 시작
public List<SVO> mtd_Select() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/Dwp_Ch12_JDBC_Bean?";
url += "useSSL=false&";
url += "useUnicode=true&";
url += "characterEncoding=UTF8&";
url += "serverTimezone=UTC";
String user = "root";
String password = "1234";
objConn = DriverManager.getConnection(url, user, password);
//out.print("DB 접속 OK!!!");
/* 매개변수가 없는 SQL 시작(주로 Select) */
String sql = "select num, uid, upw, uAge, gender, joinTM ";
sql += " from member order by num desc";
objStmt = objConn.createStatement();
objRS = objStmt.executeQuery(sql);
// JDBC 로 반환된 데이터가
// VO의 필드를 초기화하는 Setter의 인수에 사용됨
// 반환되는 데이터(row)가 2개 이상일 경우
// (next( )메서드 사용법에 주의, if와 while을 함께 사용하면 커서위치가 달라질 수 있음)
SVO objSVO = null;
objList = new Vector<SVO>();
while (objRS.next()) {
objSVO = new SVO();
objSVO.setNum(objRS.getInt("num"));
objSVO.setUid(objRS.getString("uid"));
objSVO.setUpw(objRS.getString("upw"));
objSVO.setuAge(objRS.getInt("uAge"));
objSVO.setGender(objRS.getInt("gender"));
objSVO.setJoinTM(objRS.getString("joinTM"));
objList.add(objSVO);
}
/* 매개변수가 없는 SQL 끝(주로 Select) */
} catch (ClassNotFoundException cnfe) {
System.out.print(cnfe.getMessage());
} catch (SQLException sqle) {
System.out.print(sqle.getMessage());
}
return objList;
}
// 데이터 조회(=회원 목록 출력) 끝
// 개별 회원 목록 삭제 시작
public int mtd_Del(int num) {
int rtnCnt = 0;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/Dwp_Ch12_JDBC_Bean?";
url += "useSSL=false&";
url += "useUnicode=true&";
url += "characterEncoding=UTF8&";
url += "serverTimezone=UTC";
String user = "root";
String password = "1234";
objConn = DriverManager.getConnection(url, user, password);
//out.print("DB 접속 OK!!!");
/* 매개변수가 있는 SQL 시작 */
String sql1 = "delete from member where num=?";
objPstmt = objConn.prepareStatement(sql1);
objPstmt.setInt(1, num);
rtnCnt = objPstmt.executeUpdate();
/* 매개변수가 있는 SQL 끝 */
objPstmt.close();
objConn.close(); // GC, Garbage Collector, 가비지 컬렉터,
// 메모리 자료 정리기
} catch (ClassNotFoundException cnfe) {
System.out.println(cnfe.getMessage());
} catch (SQLException sqle) {
System.out.println(sqle.getMessage());
}
return rtnCnt;
}
// 개별 회원 목록 삭제 끝
// 복수 회원 목록 삭제 시작
public int mtd_MultiDel(String[] num) {
int rtnCnt = 0;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/Dwp_Ch12_JDBC_Bean?";
url += "useSSL=false&";
url += "useUnicode=true&";
url += "characterEncoding=UTF8&";
url += "serverTimezone=UTC";
String user = "root";
String password = "1234";
objConn = DriverManager.getConnection(url, user, password);
//out.print("DB 접속 OK!!!");
/* 매개변수가 있는 SQL 시작 */
int cnt = 0;
for (int i=0; i<num.length; i++) {
String sql1 = "delete from member where num=?";
objPstmt = objConn.prepareStatement(sql1);
objPstmt.setInt(1, Integer.parseInt(num[i]));
//System.out.println("objPstmt : " + objPstmt.toString());
cnt = objPstmt.executeUpdate();
rtnCnt += cnt;
}
/* 매개변수가 있는 SQL 끝 */
objPstmt.close();
objConn.close(); // GC, Garbage Collector, 가비지 컬렉터,
// 메모리 자료 정리기
} catch (ClassNotFoundException cnfe) {
System.out.println(cnfe.getMessage());
} catch (SQLException sqle) {
System.out.println(sqle.getMessage());
}
return rtnCnt;
}
}
개별 회원 목록 삭제에서는
먼저 DB에 접속하고 String sql에 쿼리문을 초기화한다.
sql에서 사용하는 그대로 delete from T/N where C/N = ?
objPstmt에서 쿼리문을 전송하고,
그안에는 보낼 값도 들어있다.
성공적으로 적용되면 rtnCnt가 올라간다.
(약간 우주항공미사일 발사 과정 같기도 ??)
복수 회원 목록 삭제에서는 단수가 아닌 복수라..
배열이 들어간다.
그리고 배열의 수 만큼 반복해야 하므로 for구문도 들어간다..
역시 objPstmt에 세팅하는 것도 배열이 들어가게된다.
프로젝트명 : Dwp_Ch12_JDBC_Bean_update (회원 정보 수정)
<%@page import="pack_Bean.SVO"%>
<%@page import="java.util.List"%>
<%@page import="java.sql.SQLException"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" autoFlush="true" %>
<jsp:useBean id="objDAO" class="pack_Bean.DAO" scope="page" />
<%
List<SVO> objList = objDAO.mtd_Select();
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>회원목록</title>
<link rel="shortcut icon" href="#">
<link rel="stylesheet" href="/style/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="/script/script.js"></script>
</head>
<body>
<div id="wrap" class="selectWrap">
<h1>회원목록 (회원 정보 수정용)</h1>
<hr>
<table id="memListTBL">
<tbody>
<tr>
<th>번호</th>
<th>아이디</th>
<th>비밀번호</th>
<th>나이</th>
<th>성별</th>
<th>가입시간</th>
</tr>
<% for (int i=0; i<objList.size(); i++) {
SVO objSVO = objList.get(i);
String gender = "M";
if (objSVO.getGender() == 2) gender = "F";
%>
<tr>
<td><%=objSVO.getNum() %></td>
<td>
<a href="/update/memRead.jsp?num=<%=objSVO.getNum()%>" >
<%=objSVO.getUid() %>
</a>
</td>
<td><%=objSVO.getUpw() %></td>
<td><%=objSVO.getuAge() %></td>
<td><%=gender %></td>
<td>
<%=objSVO.getJoinTM() %>
</td>
</tr>
<% } %>
</tbody>
<tfoot>
<tr>
<td colspan="4"> </td>
<td colspan="2">
<button type="button" onclick="location.href='/index.jsp'">
Main
</button>
</td>
</tr>
</tfoot>
</table>
<!-- table#memListTBL -->
</div>
<!-- div#wrap -->
</body>
</html>
먼저 전체 회원을 조회하여 수정할 데이터(row)를 선택하면 수정이 가능하도록 구성.
DAO에 있는 select 메서드로 조회를 우선!
<%@ page import="pack_Bean.SVO" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" autoFlush="true" %>
<jsp:useBean id="objDAO" class="pack_Bean.DAO" />
<%
int num = Integer.parseInt(request.getParameter("num"));
//out.print("num : " + num);
SVO objSVO = objDAO.mtd_Read(num);
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="shortcut icon" href="#">
<link rel="stylesheet" href="/style/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="/script/script.js"></script>
</head>
<body>
<div id="wrap" class="readWrap">
<h1>내용보기 페이지</h1>
<hr>
<div class="dFlex">
<p class="readLabel">
<span>아이디</span>
</p>
<p><%=objSVO.getUid() %></p>
</div>
<div class="dFlex">
<p class="readLabel">
<span>비밀번호</span>
</p>
<p><%=objSVO.getUpw() %></p>
</div>
<div class="dFlex">
<p class="readLabel">
<span>나이</span>
</p>
<p><%=objSVO.getuAge() %></p>
</div>
<div class="dFlex">
<p class="readLabel">
<span>성별</span>
</p>
<p>
<%
if (objSVO.getGender() == 1) {
out.print("남");
} else {
out.print("여");
}
%>
</p>
</div>
<div class="readBtnArea">
<button type="button"
onclick="location.href='/update/memUpdate.jsp?num=<%=num%>'">
내용 수정
</button>
<button type="button"
onclick="location.href='/update/memList.jsp'">
목록보기
</button>
<button type="button"
onclick="location.href='/index.jsp'">
메인
</button>
</div>
</div>
<!-- div#wrap -->
</body>
</html>
수정할 데이터를 클릭했다면 이 곳으로 이동되는데, 내용 수정 버튼, 목록으로 돌아가기 버튼, 메인으로 돌아가기 버튼을
만들고 수정할 데이터를 출력!
<%@ page import="pack_Bean.SVO" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" autoFlush="true" %>
<jsp:useBean id="objDAO" class="pack_Bean.DAO" />
<%
int num = Integer.parseInt(request.getParameter("num"));
//out.print("num : " + num);
SVO objSVO = objDAO.mtd_Read(num);
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="shortcut icon" href="#">
<link rel="stylesheet" href="/style/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="/script/script.js"></script>
</head>
<body>
<div id="wrap" class="readWrap">
<h1>내용수정 페이지</h1>
<hr>
<div class="dFlex">
<p class="readLabel">
<span>아이디</span>
</p>
<p><%=objSVO.getUid() %></p>
</div>
<div class="dFlex">
<p class="readLabel">
<span>비밀번호</span>
</p>
<p>
<input type="text" name="upw" form="updateFrm"
value="<%=objSVO.getUpw() %>">
</p>
</div>
<div class="dFlex">
<p class="readLabel">
<span>나이</span>
</p>
<p>
<input type="text" name="uAge" form="updateFrm"
value="<%=objSVO.getuAge() %>">
</p>
</div>
<div class="dFlex">
<p class="readLabel">
<span>성별</span>
</p>
<p>
<%
if (objSVO.getGender() == 1) {
out.print("남");
} else {
out.print("여");
}
%>
</p>
</div>
<div class="readBtnArea">
<button form="updateFrm" id="updateBtn">
수정하기
</button>
<button type="button"
onclick="location.href='/update/memList.jsp'">
목록보기
</button>
<button type="button"
onclick="location.href='/index.jsp'">
메인
</button>
</div>
</div>
<!-- div#wrap -->
<form id="updateFrm">
<input type="hidden" name="num" value="<%=num%>">
</form>
</body>
</html>
수정할 데이터는 비밀번호 또는 나이. 그것들의 값은 버튼을 누르면 form요소로 num값이 넘어가게 된다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" autoFlush="true" %>
<jsp:useBean id="objDAO" class="pack_Bean.DAO" />
<%
int num = Integer.parseInt(request.getParameter("num"));
String upw = request.getParameter("upw");
int uAge = Integer.parseInt(request.getParameter("uAge"));
//out.print("num : " + num);
int rtnCnt = objDAO.mtd_Update(num, upw, uAge);
/* 서버측에서 페이지 이동 시작 */
if (rtnCnt == 1) {
response.sendRedirect("/update/memRead.jsp?num="+num);
}
/* 서버측에서 페이지 이동 끝 */
%>
'코딩 해보자' 카테고리의 다른 글
| 220922 FileUpload를 해봅시다. (0) | 2022.09.22 |
|---|---|
| 220921 JDBC를 더 간단하게, DBCP API 사용으로 효율을 높이자 (1) | 2022.09.21 |
| 220919 JDBC+Bean 연동하기 복습 (1) | 2022.09.19 |
| 220916 jsp와 DB서버를 연동하여 입력된 회원 삭제 하기 (2) | 2022.09.16 |
| 220914 JSP - Java - SQL(DB) 연결 (0) | 2022.09.14 |
댓글