Notice
Recent Posts
Recent Comments
Link
Everything has an expiration date
[JSP & JDBC & Oracle] 20231217 처음부터 재작성 복습 ① - 회원 명단 관리(Member) 모든 페이지 재작성 코드 (Practice_MemberSelect ~ Practice_MemberDelete) 본문
[JSP & JDBC & Oracle]/Program source (JSP & JDBC & Oracle)
[JSP & JDBC & Oracle] 20231217 처음부터 재작성 복습 ① - 회원 명단 관리(Member) 모든 페이지 재작성 코드 (Practice_MemberSelect ~ Practice_MemberDelete)
Jelly-fish 2023. 12. 18. 01:07
◎ 작성한 페이지 이동 ◎
http://211.238.142.178:3306/WebApp12/Practice_MemberSelect.jsp
01234567
MemberDTO.java
/*===============================================
MemberDTO.java
- 객체 전용(데이터 보관 및 전송) → JAVA Bean
=================================================*/
package com.test;
public class MemberDTO
{
// 주요 속성 구성(프로퍼티 구성)
private String sid, name, tel; //-- 번호, 이름, 전화번호
// getter / setter 구성
public String getSid()
{
return sid;
}
public void setSid(String sid)
{
this.sid = sid;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getTel()
{
return tel;
}
public void setTel(String tel)
{
this.tel = tel;
}
}
MemberDAO.java
1. 주요 속성 구성, 데이터베이스 연결 담당 메소드
`Connection connection()`
// 주요 속성 구성
private Connection conn;
// 데이터베이스 연결 담당 메소드
public Connection connection() throws ClassNotFoundException, SQLException
{
conn = DBConn.getConnection();
return conn;
}
2. 회원 데이터 입력 담당 메소드
`int add(MemberDTO dto)`
// 데이터 입력 담당 메소드
public int add(MemberDTO dto) throws SQLException
{
int result = 0;
String sql = "INSERT INTO TBL_MEMBER(SID, NAME, TEL) VALUES(MEMBERSEQ.NEXTVAL, ?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, dto.getName());
pstmt.setString(2, dto.getTel());
result = pstmt.executeUpdate();
pstmt.close();
return result;
}
3. 회원 리스트 전체 출력 담당 메소드
`ArrayList<MemberDTO> lists()`
// 회원 리스트 전체 출력 담당 메소드
public ArrayList<MemberDTO> lists() throws SQLException
{
ArrayList<MemberDTO> result = new ArrayList<MemberDTO>();
String sql = "SELECT SID, NAME, TEL FROM TBL_MEMBER ORDER BY SID";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
MemberDTO dto = new MemberDTO();
dto.setSid(rs.getString("SID"));
dto.setName(rs.getString("NAME"));
dto.setTel(rs.getString("TEL"));
result.add(dto);
}
rs.close();
pstmt.close();
return result;
}
4. 전체 회원 수 확인 담당 메소드
`int count()`
// 전체 회원 수 확인 담당 메소드
public int count() throws SQLException
{
int result = 0;
String sql = "SELECT COUNT(*) AS COUNT FROM TBL_MEMBER";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
result = rs.getInt("COUNT");
}
rs.close();
pstmt.close();
return result;
}
5. 번호 검색 담당 메소드
`MemberDTO searchMember(String sid)`
// 메소드 추가
// 번호 검색 담당 메소드(번호를 통해 회원 데이터 조회)
//-- 현재... 번호(sid)는 TBL_MEMBER 테이블에서 식별자의 역할을 수행하고 있으며
// 이로인해 번호를 통한 검색 결과는 한 명의 회원일 수 밖에 없기 때문에
// 반환 자료형은 MemberDTO 형태로 구성한다.
// 회원 정보 검색 메소드 (SID)
public MemberDTO searchMember(String sid) throws SQLException
{
MemberDTO result = new MemberDTO();
String sql = "SELECT SID, NAME, TEL FROM TBL_MEMBER WHERE SID=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
// pstmt.setString(1, sid);
pstmt.setInt(1, Integer.parseInt(sid));
ResultSet rs = pstmt.executeQuery();
//if (rs.next())
while (rs.next())
{
result.setSid(rs.getString("SID"));
result.setName(rs.getString("NAME"));
result.setTel(rs.getString("TEL"));
}
rs.close();
pstmt.close();
return result;
}
6. 회원 데이터 수정 담당 메소드
`int modify(MemberDTO member)`
// 메소드 추가
// 회원 데이터 수정 담당 메소드
public int modify(MemberDTO member) throws SQLException
{
int result = 0;
String sql = "UPDATE TBL_MEMBER"
+ " SET NAME=?, TEL=?"
+ " WHERE SID=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, member.getName());
pstmt.setString(2, member.getTel());
// pstmt.setString(3, dto.getSid());
pstmt.setInt(3, Integer.parseInt(member.getSid()));
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
// 가급적이면 타입은 맞춰주는 것이 좋다.
// Oracle 상에서는 sid가 NUMBER 타입이기 때문에
// String으로 받아온 sid를 Integer 타입으로 변경해 준 것이다.
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
result = pstmt.executeUpdate();
pstmt.close();
return result;
}
7. 참조 데이터(회원의 성적 데이터) 레코드 수 확인 메소드
- TBL_MEMBERSCORE의 레코드(회원 성적 데이터)를
TBL_MEMBER의 SID(번호)가 몇 개를 참조하고 있는지 확인
1 이상 (성적 레코드 참조함) | → 삭제 불가능. |
---|---|
0 (성적 레코드 참조하지 않음) | → 바로 삭제 가능! |
`int refCount(String sid)`
// 참조 데이터 레코드 수 확인 메소드
public int refCount(String sid) throws SQLException
{
int result = 0;
String sql = "SELECT COUNT(*) AS COUNT"
+ " FROM TBL_MEMBERSCORE"
+ " WHERE SID=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, Integer.parseInt(sid));
ResultSet rs = pstmt.executeQuery();
while(rs.next())
{
result = rs.getInt("COUNT");
}
rs.close();
pstmt.close();
return result;
}
8. 데이터베이스 연결 종료(해제) 담당 메소드
`void close()`
// 데이터베이스 연결 종료(해제) 담당 메소드
public void close() throws SQLException
{
DBConn.close();
}
【회원 명단 관리 페이지】 - Practice_MemberSelect.jsp
Practice_MemberSelect.jsp
<%@page import="com.test.MemberDAO"%>
<%@page import="com.test.MemberDTO"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%
// Practice_MemberSelect.jsp
// dao의 전체 항목 MemberDTO ArrayList를 반환받는 메소드 lists() 호출
// while 문을 돌면서, 번호, 이름, 전화번호 항목에
// 메소드를 통해 가져온 값을 하나씩 출력,
// 수정을 클릭했을 때 → href URL에 sid 가 전달되도록.
// 삭제를 클릭했을 때 → 자바스크립트 함수 정말 삭제할 것인지 묻는 메소드
// memberDelete(sid, name) 을 호출하여
// confirm("안내문") 의 값이 true 일 때 (삭제한다고 결정했을 때)
// 삭제가 되도록
// + 자식 레코드가 없을 때만...
// dao.lists() 메소드를 이용하여...
// 전체 리스트를 출력하기
MemberDAO dao = new MemberDAO();
//dao.lists() → ArrayList<MemberDTO> 반환
StringBuffer str = new StringBuffer();
str.append("<table class='table' style=\"text-align: center;\">");
str.append(" <tr>");
str.append(" <th style='width: 10%'>번호</th>");
str.append(" <th style='width: 20%'>이름</th>");
str.append(" <th style='width: 40%'>전화번호</th>");
str.append(" <th style='width: 30%'>관리</th>");
str.append(" </tr> ");
try
{
dao.connection();
for (MemberDTO member : dao.lists())
{
str.append("<tr>");
str.append(" <td>" + member.getSid() + "</td>");
str.append(" <td>" + member.getName() + "</td>");
str.append(" <td>" + member.getTel() +"</td>");
str.append(" <td>");
str.append(" <a href='Practice_MemberUpdateForm.jsp?sid=" + member.getSid() + "'>");
str.append(" <button type='button' class='btn01'>수정</button>");
str.append(" </a>");
/* <a href='javascript:memberDelete(1, "홍길동")'> */
str.append(" <a href='javascript:memberDelete(" + member.getSid() + ", \"" + member.getName() + "\")'>");
str.append(" <button type='button' class='btn01'>삭제</button>");
str.append(" </a>");
str.append(" </td>");
str.append("</tr>");
}
str.append("</table>");
}
catch(Exception e)
{
System.out.println(e.toString());
}
finally
{
try
{
dao.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Practice_MemberSelect.jsp</title>
<link rel="stylesheet" type="text/css" href="css/MemberScore.css">
<style type="text/css">
a {text-decoration: none;}
</style>
<script type="text/javascript">
function memberDelete(sid, name)
{
//alert("함수 호출 확인~!!!");
// ① 정말로 이 회원의 정보를 삭제할건지 묻기.
// → confirm
// : [확인] 클릭시 : true 반환
// : [취소] 클릭시 : false 반환
var isOkDel = confirm("번호 : " + sid + ", 이름 : " + name + "\n정말로 이 회원의 정보를 삭제하시겠습니까?");
// ② 클라이언트가 정말로 삭제하겠다고 응답했다면
// window.location.href = "Practice_MemberDelete.jsp?sid=" + sid;
// 형태로 클라이언트의 브라우저 주소를 회원 삭제 페이지로 이동시키기.
if (isOkDel)
window.location.href = "Practice_MemberDelete.jsp?sid=" + sid;
// http://localhost:3306/WebApp12/Practice_MemberDelete.jsp?sid=1
// ★ ̄ ̄ ̄
// (sid 값이 제대로 전달됨을 확인.)
//■■■■■■■■■■■■■■■■■■■■■■■■■
// Practice_MemberDelete.jsp 에서 처리할 사항임!
// Javascript 단에서 처리하는 로직이 아니다.
//■■■■■■■■■■■■■■■■■■■■■■■■■
// ③ 확인을 눌렀을 경우 바로 데이터 삭제 Ⅹ
// - 성적 데이터가 존재한다면 자식 레코드가
// 존재하는 것이므로 데이터 삭제가 불가능하다.
// 성적 데이터가 존재하는지 확인하는 메소드
// -----------------------------------------------------
// → dao.refCount(sid)
// : sid값에 해당하는 성적 데이터가 존재하는지 확인.
// -----------------------------------------------------
}
</script>
</head>
<body>
<div>
<h1>회원 <span>명단</span> 관리 및 출력 페이지</h1>
<hr>
</div>
<div>
<a href='Practice_MemberScoreSelect.jsp'>
<button type="button">회원 성적 관리</button>
</a>
<a href='Practice_MemberInsertForm.jsp'>
<button type="button">신규 회원 등록</button>
</a>
</div>
<br /><br />
<!--=========================================================================-->
<!-- 정적인 테이블 구성 -->
<!--=========================================================================-->
<!--
<div>
<table class='table' style="text-align: center;">
<tr>
<th style="width: 10%">번호</th>
<th style="width: 20%">이름</th>
<th style="width: 40%">전화번호</th>
<th style="width: 30%">관리</th>
</tr>
<tr>
<td>1</td>
<td>홍길동</td>
<td>010-3434-3434</td>
<td>
<a href="Practice_MemberUpdateForm.jsp?sid=" + 1>
<button type="button" class="btn">수정</button>
</a>
<a href="javascript:memberDelete(1, '홍길동')">
<button type="button" class="btn">삭제</button>
</a>
</td>
</tr>
</table>
</div>
-->
<!--=========================================================================-->
<!-- 젠코딩 (Emmet) 한번 해보기 ㅎㅎ -->
<!--
① tr>td{1}+td{홍길동}+td>(a[href="Practice_MemberUpdateForm.jsp?sid=1"]>(button[type="button"].btn{수정}))+(a[href="javascript:memberDelete(1, '홍길동')"]>button[type="button"].btn{삭제})
② table>(tr>td{1}+td{홍길동}+td>(a[href="Practice_MemberUpdateForm.jsp?sid=1"]>(button[type="button"].btn{수정}))+(a[href="javascript:memberDelete(1, '홍길동')"]>button[type="button"].btn{삭제}))
③ tr>td{1}+td{홍길동}+td{010-3434-3434}+td>(a[href="Practice_MemberUpdateForm.jsp?sid=1"]>(button[type="button"].btn{수정}))+(a[href="javascript:memberDelete(1, '홍길동')"]>button[type="button"].btn{삭제})
④ table>(tr>td{1}+td{홍길동}+td{010-3434-3434}+td>(a[href="Practice_MemberUpdateForm.jsp?sid=1"]>(button[type="button"].btn{수정}))+(a[href="javascript:memberDelete(1, '홍길동')"]>button[type="button"].btn{삭제}))
-->
<!--
<table>
<tr>
<td>1</td>
<td>홍길동</td>
<td>010-3434-3434</td>
<td><a href="Practice_MemberUpdateForm.jsp?sid=1"><button type="button" class="btn">수정</button></a><a href="javascript:memberDelete(1, '홍길동')"><button type="button" class="btn">삭제</button></a></td>
</tr>
</table>
-->
<!-- 스크립트릿에서 생성한 동적 테이블 구성. -->
<div>
<%=str.toString() %>
</div>
</body>
</html>
Ⅰ [회원 데이터 입력] - Practice_MemberInsertForm.jsp, Practice_MemberInsert.jsp
Practice_MemberInsertForm.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Practice_MemberInsertForm.jsp</title>
<link rel="stylesheet" type="text/css" href="css/MemberScore.css">
<style type="text/css">
a {text-decoration: none;}
</style>
<script type="text/javascript">
// 이름이 제대로 입력됐을 경우
// Practice_MemberInsert.jsp 페이지로 이동하여
// 회원 입력이 이루어지도록 하는 함수
function memberSubmit()
{
//alert("함수 호출 확인~!!");
// ① 이름 값, 에러 메시지를 가져온다. (객체로)
// → document.getElementById("id");!!
// 자바스크립트에서 객체를 가져올 때는 항상 ID를 쓴다는 것을 잊지 말자.
// [왜 그랬어?]========================================
//var userName = document.getParameter("userName");
//var nameMsg = document.getParameter("nameMsg");
// ====================================================
var userName = document.getElementById("userName");
var nameMsg = document.getElementById("nameMsg");
// ② 에러 메시지를 보이지 않게 한다.
nameMsg.style.display = "none";
// ③ 이름 값이 공백일 경우 에러 메시지를 보이도록 변경한다.
// 이름 입력 칸에 focus를 준다.
if (userName.value == "")
{
nameMsg.style.display = "inline";
userName.focus();
return;
}
// ④ 이름 값이 공백이 아닐 경우 form을 submit 한다.
memberForm.submit();
}
// 취소 버튼을 눌렀을 때,
// 입력 값이 초기화되도록 하는 함수
function memberReset()
{
// ① 에러 메시지 객체와 이름 입력 객체를 가져온다.
var nameMsg = document.getElementById("nameMsg");
var userName = document.getElementById("userName");
// ② 에러 메시지를 전부 보이지 않게 변경한다.
nameMsg.style.display = "none";
// ③ memberForm 을 reset() 시킨다.
memberForm.reset();
// ④ 이름 입력 칸에 focus 를 준다.
userName.focus();
}
</script>
</head>
<body>
<!-- 회원 정보를 입력하는 폼 -->
<!-- 회원 정보 수정 폼을 만들기 전에 생성! 그대로 가져다 쓰면 됨. -->
<!--
[페이지 형식 구상]
회원 정보 입력 페이지
_________________________________________________
이름 [ ]
전화번호 [ ]
[ 확인 ] [ 취소 ]
_________________________________________________
[확인 클릭시]
: 입력하는 페이지로 이동. 클라이언트에게 노출되지 않음.
(Practice_MemberInsert.jsp)
[취소 클릭시]
: 모든 입력값이 초기화 됨.
-->
<!--
h1{회원 정보 입력 페이지}
hr
(tr>th{이름}+td>(input[name="userName"][type="txt"][id="userName"]))
(tr>th{전화번호}+td>(input[name="userTel"][type="txt"]))
(tr>th{이름}+td>(input[name="userName"][type="txt"][id="userName"]))+(tr>th{전화번호}+td>(input[name="userTel"][type="txt"]))
table>(tr>th{이름}+td>(input[name="userName"][type="txt"][id="userName"]))+(tr>th{전화번호}+td>(input[name="userTel"][type="txt"]))
-->
<!-- ○ table에 테두리 추가하기. -->
<!-- table[border="1"] -->
<!-- ○ th에 스타일 추가하기. -->
<!-- th[style="width: 40px;"] -->
<div>
<h1>회원 정보 <span style="color: red;">입력</span>페이지</h1>
<hr />
</div>
<!-- div>a[href="Practice_MemberSelect.jsp"]>button[type="button"].btn{회원 명단 관리} -->
<div>
<a href="Practice_MemberSelect.jsp">
<button type="button" class="btn">회원 명단 관리</button>
</a>
</div>
<br />
<div>
<form action="Practice_MemberInsert.jsp" method="post" name="memberForm">
<table class='table'>
<tr>
<th>이름</th>
<td><input type="text" name="userName" id="userName" /></td>
<td><span class="errMsg" id="nameMsg">이름을 입력해야 합니다.</span></td>
<!-- td>span.errMsg[name="nameMsg"]{이름을 입력해야 합니다.} -->
</tr>
<tr>
<th>전화번호</th>
<td><input type="text" name="userTel" /></td>
</tr>
<!-- <button type="button"> 으로 type을 설정해 주지 않으면
어떤 버튼을 누르든 모두 submit() 되어버려서
<form action="Practice_MemberInsert.jsp">로 이동되는
에러를 겪었다...
정말 이런 경험 다신 하고싶지 않아... -->
<tr>
<td></td>
<td>
<a href="javascript:memberSubmit()">
<button type="button" class="btn">입력하기</button>
</a>
<a href="javascript:memberReset()">
<button type="button" class="btn">취소하기</button>
</a>
<a href="Practice_MemberSelect.jsp">
<button type="button" class="btn">목록으로</button>
</a>
</td>
</tr>
</table>
</form>
</div>
<!-- [입력하기, 취소하기 버튼 Emmet 연습.] -->
<!-- ★ [<button> 의 경우에는, value에 '입력하기'를 넣는게 아니라 태그 사이에 구성한다.] -->
<!-- ★ [<input type="button" value="입력하기"> <input> 태그일 경우에만 value에 넣는 것이다!] -->
<!-- tr>(td>a[href="Practice_MemberInsert.jsp"]>(button.btn01[value="입력"]))+(td>a[href="javascript:reset()"]>(button.btn01[value="취소"])) -->
</body>
</html>
Practice_MemberInsert.jsp
<%@page import="com.test.MemberDTO"%>
<%@page import="com.test.MemberDAO"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%
// [<form action="대상페이지" method="post"> 로 구성했을 때]
// 【이전 페이지(Practice_MemberInsert.jsp)로부터 넘어온 데이터를 수신하기 전에】
//★【반드시 《 인 코 딩 을 먼 저 바 꾸 어 주 어 야 한 다!!!!! 》】
// → 『request.setCharacterEncoding("UTF-8");』
request.setCharacterEncoding("UTF-8");
// ① 이전 페이지(Practice_MemberInsert.jsp)로부터 넘어온 데이터를 수신한다.
// → userName, userTel
// [request.getParameter() 메소드 사용. → 반환값 : String]
String name = request.getParameter("userName");
String tel = request.getParameter("userTel");
// ② MemberDAO의 인스턴스를 생성한다.
MemberDAO dao = new MemberDAO();
// 만약, MemberDAO의 생성자에 데이터베이스 연결 기능을 넣어뒀다면
// MemberDAO 의 객체를 생성할 때부터 데이터베이스 연결 예외(SQLException, ClassNotFoundException)가
// 발생할 수 있기 때문에
// [MemberDAO dao = null] 로 먼저 선언을 해 둔 후에
// try~catch 문 안에서 dao의 객체 생성(생성자 호출)을 해야 한다.
/*
*****************************************************************
[MemberDAO 생성자에 데이터베이스 연결 기능 삽입]
*****************************************************************
private Connection conn;
public MemberDAO()
{
conn = DBConn.getConnection();
}
*****************************************************************
→ 이렇게 MemberDAO 를 구성했을 경우...
dao의 메소드를 사용하려 할 때 다음과 같이 작성해야 한다.
▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦
MemberDAO dao = null
try
{
dao = new MemberDAO();
}
catch(Exception e)
{
System.out.println(e.toString());
}
▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦▦
*/
// ③ 데이터베이스와 연결하는 부분에 있어서, 예외(Exception)를 throws 했기 때문에
// 아래의 처리들은 try~catch로 구성한다.
try
{
// ④ MemberDAO dao 의 메소드인 connection을 통해 데이터 베이스와 연결한다.
dao.connection();
// ⑤ MemberDTO member 객체를 생성한다.
// → 데이터베이스에 회원 정보를 INSERT INTO 하는 메소드인 add 메소드가
// int add(MemberDTO member) 매개변수를 MemberDTO를 받기 때문이다.
MemberDTO member = new MemberDTO();
// ⑥ Practice_MemberInsertForm.jsp에서 사용자가 입력했던 값들을
// MemberDTO member 객체에 set 해 준다.
member.setName(name);
member.setTel(tel);
// ⑦ add 메소드를 통해 데이터베이스에 클라이언트가 입력한 회원 정보를 INSERT 한다.
dao.add(member);
}
catch(Exception e)
{
System.out.println(e.toString());
}
finally
{
try
{
dao.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
// ⑧ 데이터 입력을 끝마쳤기 때문에, 회원 목록 페이지로 클라이언트를 이동시킨다.
response.sendRedirect("Practice_MemberSelect.jsp");
// 아래 부분은 모두 삭제한다.
// Insert를 처리하는 이 페이지는 클라이언트에게 노출되지 않고
// 페이지 뒷단의 로직을 처리하는 페이지이기 때문이다.
%>
Ⅱ [회원 데이터 수정] - Practice_MemberUpdateForm.jsp, Practice_MemberUpdate.jsp
Practice_MemberUpdateForm.jsp
<%@page import="com.test.MemberDTO"%>
<%@page import="com.test.MemberDAO"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%
// ① 이전 페이지(Practice_MemberSelect.jsp)로부터 넘어온 데이터를 수신한다.
// → sid
// [request.getParameter("sid");]
String sid = request.getParameter("sid");
// sid의 경우, method="post" 방식이 아니라, "get" 방식으로 url을 통해 전송되었고
// 한글 형식의 문자가 아니기 때문에 인코딩을 변경해 주지 않아도 괜찮다.
//=======================================================
// 원본데이터를 찾아서 이름 입력창, 전화번호 입력창의
// value 속성값으로 넣어주기 위해서
// name, tel에 해당하는 String 타입 문자열 변수를
// ★ 【전역변수】로 선언해 준다.
//=======================================================
String name = "";
String tel = "";
//★ [Check~!!!]
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// → 전역변수로 선언을 하지않고, try~catch문 내부에 선언해 버리면
// 지역변수가 되어 버려서 입력창의 value에 넣어줄 수 없게 된다.
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// ② MemberDAO 객체를 생성한다.
MemberDAO dao = new MemberDAO();
try
{
// ③ try~catch문 내부에 데이터베이스와 연결하는 MemberDAO의 메소드
// [ connection() ]을 통해 데이터베이스와 연결한다.
dao.connection();
// ④ 수정하려는 회원의 sid를 통해, 원본 데이터를 찾아내어
// 입력창에 뿌려 주어야 한다.
// 이때 사용할 메소드는 MemberDAO의
// → 【MemberDTO searchMember(String sid)】 이다.
MemberDTO member = dao.searchMember(sid);
// ⑤ searchMember(String sid)를 통해, 원본 데이터에 해당하는
// MemberDTO 객체를 반환받았다면,
// 그 객체의 getName(), getTel()을 통해 원본 문자열 값을 받아와서
// String name, tel에 저장해 준 후,
// 이름 입력창, 전화번호 입력창에 그 값을 value로 넣어준다.
name = member.getName();
tel = member.getTel();
}
catch(Exception e)
{
System.out.println(e.toString());
}
finally
{
try
{
dao.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Practice_MemberUpdateForm.jsp</title>
<link rel="stylesheet" type="text/css" href="css/MemberScore.css">
<style type="text/css">
a {text-decoration: none;}
</style>
<script type="text/javascript">
// 이름이 제대로 입력됐을 경우
// Practice_MemberInsert.jsp 페이지로 이동하여
// 회원 입력이 이루어지도록 하는 함수
function memberSubmit()
{
//alert("함수 호출 확인~!!");
// ① 이름 값, 에러 메시지를 가져온다. (객체로)
// → document.getElementById("id");!!
// 자바스크립트에서 객체를 가져올 때는 항상 ID를 쓴다는 것을 잊지 말자.
var userName = document.getElementById("userName");
var nameMsg = document.getElementById("nameMsg");
// ② 에러 메시지를 보이지 않게 한다.
nameMsg.style.display = "none";
// ③ 이름 값이 공백일 경우 에러 메시지를 보이도록 변경한다.
// 이름 입력 칸에 focus를 준다.
if (userName.value == "")
{
nameMsg.style.display = "inline";
userName.focus();
return;
}
// ④ 이름 값이 공백이 아닐 경우 form을 submit 한다.
memberForm.submit();
}
// 취소 버튼을 눌렀을 때,
// 입력 값이 초기화되도록 하는 함수
function memberReset()
{
// ① 에러 메시지 객체와 이름 입력 객체를 가져온다.
var nameMsg = document.getElementById("nameMsg");
var userName = document.getElementById("userName");
// ② 에러 메시지를 전부 보이지 않게 변경한다.
nameMsg.style.display = "none";
// ③ memberForm 을 reset() 시킨다.
memberForm.reset();
// ④ 이름 입력 칸에 focus 를 준다.
userName.focus();
}
</script>
</head>
<body>
<!--
[페이지 형식 구상]
회원 정보 수정 페이지
_________________________________________________
이름 [ 홍길동 ] (이전 데이터)
전화번호 [ 010-3434-3434 ] (이전 데이터)
[ 확인 ] [ 취소 ]
_________________________________________________
(* 사용자가 수정하기 버튼을 눌러서 이 페이지로 이동 됐을 때.
기본적으로 원본 데이터가 입력창에 들어있는 상태이다. )
[확인 클릭시]
: 수정하는 페이지로 이동. 클라이언트에게 노출되지 않음.
(Practice_MemberUpdate.jsp)
[취소 클릭시]
: 모든 입력값 데이터가 이전 데이터 값으로 돌아감
-->
<div>
<h1>회원 정보 <span style="color: aqua;">수정</span>페이지</h1>
<hr />
</div>
<div>
<!-- 수정할 대상의 sid가 몇인지를 알아야 대상을 특정지어서 수정할 수 있기 때문에-->
<!-- get 방식으로 url에 직접 sid를 넘겨주는 처리를 해 주었다.-->
<!-- 이 방식 외에 사용할 수 있는 방법은 -->
<!--======================================================================================-->
<!-- 【① <input type="hidden"> 으로 처리하는 방식】 -->
<%-- ① <input type="hidden" name="sid" value="<%=sid%>"> --%>
<!--======================================================================================-->
<!-- 【② <input type="text" disabled="disabled"> 로 처리하는 방식】 -->
<!-- (* 사용자가 볼 수는 있지만, 입력할 수는 없는 형태로 구성한 것.) -->
<%-- ② <input type="text" name="sid" value="<%=sid%>" disabled="disabled"> --%>
<!--======================================================================================-->
<form action="Practice_MemberUpdate.jsp?sid=<%=sid %>" method="post" name="memberForm">
<table class='table'>
<tr>
<th>이름</th>
<td><input type="text" name="userName" id="userName" value="<%=name%>"/></td>
<td><span class="errMsg" id="nameMsg">이름을 입력해야 합니다.</span></td>
</tr>
<tr>
<th>전화번호</th>
<td><input type="text" name="userTel" value="<%=tel %>"/></td>
</tr>
<tr>
<td></td>
<td>
<a href="javascript:memberSubmit()">
<button type="button" class="btn">수정하기</button>
</a>
<a href="javascript:memberReset()">
<button type="button" class="btn">취소하기</button>
</a>
<a href="Practice_MemberSelect.jsp">
<button type="button" class="btn">목록으로</button>
</a>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
Practice_MemberUpdate.jsp
<%@page import="com.test.MemberDTO"%>
<%@page import="com.test.MemberDAO"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%
//***********************************************************************
// 이전 페이지(Practice_MemberUpdateForm.jsp)에서는
// sid 만 넘어온 것이 아니라,
// 갱신해야할 회원의 ★『name(이름), tel(전화번호)』까지 넘어왔기 때문에
// 이름의 경우, 한글이 입력될 수 있으므로
// 【인코딩을 먼저 변경해 준 후에 데이터를 수신해 주어야 한다.】
// → request.setCharacterEncoding("UTF-8");
//***********************************************************************
request.setCharacterEncoding("UTF-8");
// ① 이전 페이지(Practice_MemberUpdateForm.jsp)로부터 넘어온 데이터 수신
// → sid, userName, userTel
String sid = request.getParameter("sid");
String name = request.getParameter("userName");
String tel = request.getParameter("userTel");
// ② MemberDAO 객체 생성
MemberDAO dao = new MemberDAO();
try
{
// ③ try~catch 문 내부에서 dao의 데이터베이스 연결 메소드 호출
// → dao.connection()
dao.connection();
// ④ MemberDTO 객체 생성
MemberDTO member = new MemberDTO();
// dao의 회원 업데이트 메소드는
// 【int modify(MemberDTO member)】 와 같이
// MemberDTO 객체를 매개변수로 받아서
// 그 객체의 속성 값(name, tel)에 해당하는 값으로
// 데이터베이스 업데이트를 진행하므로 MemberDTO 객체를 생성해 주어야 함.
// ⑤ 생성한 MemberDTO 객체에, 사용자가 입력한 수정 값을 set 해 준다.
member.setSid(sid);
member.setName(name);
member.setTel(tel);
// ⑥ dao.modify(MemberDTO member)를 통해 업데이트를 진행한다.
dao.modify(member);
}
catch(Exception e)
{
System.out.println(e.toString());
}
finally
{
try
{
dao.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
// ⑦ 업데이트를 모두 끝냈으므로, 회원 목록 페이지로 이동한다.
// → 【response.sendRedirect("Practice_MemberSelect.jsp");】
response.sendRedirect("Practice_MemberSelect.jsp");
// 아래에 있는 내용들을 모두 삭제한다.
// Practice_MemberUpdate.jsp 의 경우에도
// 클라이언트에게 노출되지 않고 페이지 뒷단의 Logic을 처리하는 페이지이기 때문이다.
%>
Ⅲ ★ [회원 데이터 삭제] - Practice_MemberDelete.jsp
Practice_MemberDelete.jsp
<%@page import="com.test.MemberDAO"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%
// 이전 페이지(Practice_MemberSelect.jsp)에서 넘어온 데이터는
// 숫자인 sid밖에 없었기 때문에 (한글 문자 없음)
// setCharacterEncoding("UTF-8");을 통해 인코딩 방식을 변경해 주지 않아도 괜찮다.
// ① 이전 페이지(Practice_MemberSelect.jsp)로부터 넘어온 데이터 수신
// → sid
String sid = request.getParameter("sid");
// ② MemberDAO 객체 생성
MemberDAO dao = new MemberDAO();
try
{
// ③ try~catch 문 내부에서 MemberDAO의 메소드인 connection()을 통해
// 데이터베이스와 연결
dao.connection();
// =======================================================
// [※ 주의 ※]
// =======================================================
// 데이터를 바로 삭제하면 안 된다!
// sid에 해당하는 성적 데이터가 존재한다면
// sid를 참조하는 자식 레코드가 존재하는 것이므로
// 삭제할 수 없게끔 처리해야 한다.
// =======================================================
// ④ dao의 메소드 중, 매개변수 sid를 받아
// 성적 레코드가 있다면 1, 없다면 0 을 반환하는
// → 【int refCount(String sid)】 를 이용하여
// 성적 레코드가 0일 때만 삭제가 가능하도록 처리해야 한다.
int childExistNum = dao.refCount(sid);
// Delete가 이상해 ㅠㅠ...
//근본 원인 (root cause)
// ※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
// java.lang.IllegalStateException
// : 응답이 이미 커밋된 후에는, sendRedirect()를 호출할 수 없습니다.
// ※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
//**********************************************************
// ⓐ 성적 레코드가 0보다 크다면
//**********************************************************
// → 삭제가 불가능하므로 Notice.jsp 페이지로
// 클라이언트를 이동시킨다.
//**********************************************************
if (childExistNum == 0)
{
dao.remove(sid);
//◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈
// ★ 여기에 response.sendRedirect("url")을 하게 되면
// 오류 발생 안 함..
//◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈
// ⑤ 모든 처리가 끝났다면, 회원 목록 리스트로 클라이언트를 이동시킨다.
response.sendRedirect("Practice_MemberSelect.jsp");
}
//**********************************************************
// ⓑ 성적 레코드가 0이라면
//**********************************************************
// → 『int dao.remove(String sid)』 메소드를 통해
// 회원 정보를 삭제한 후
// 클라이언트를 회원 목록 페이지로 이동시킨다.
// (response.sendRedirect("Practice_MemberSelect.jsp"))
//**********************************************************
else if (childExistNum > 0)
{
response.sendRedirect("Notice.jsp");
}
//◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈
// ★ 여기에 response.sendRedirect("url")을 하게 되면 오류!!
//◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈◈
// → 왜????????????????????????????????????????
// ⑤ 모든 처리가 끝났다면, 회원 목록 리스트로 클라이언트를 이동시킨다.
//response.sendRedirect("Practice_MemberSelect.jsp");
}
catch(Exception e)
{
System.out.println(e.toString());
}
finally
{
try
{
dao.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
// 아래 부분을 모두 삭제한다.
// 이 페이지는 클라이언트에게 노출되지 않고
// 페이지 뒷단의 Logic만 처리하는 부분이기 때문이다.
%>