Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

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
1 [회원 입력], 2 [회원 수정], 3 [회원 삭제]

 


 

 

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만 처리하는 부분이기 때문이다.
%>