국비지원 JAVA 풀스택 과정/JAVA

[JSP] 우편번호검색

ODaram 2022. 12. 14. 14:04
<MemberDAO.java> 
<패턴프로그래밍 부분이다.>

Connection con = null;		
 PreparedStatement pstmt = null;
 ResultSet rs = null;
 String sql = null;
 boolean flag = false;
 try {
     con = pool.getConnection();
     sql = "select id from tblMember where id =?";
     pstmt = con.prepareStatement(sql);
     pstmt.setString(1, id);
     flag = pstmt.executeQuery().next();
     /*flag = rs.next(); 	// next() 는 쿼리문의 실행 결과가 있으면 다음행으로 커서를 옮기며, 다음행이 있으면 true, 없으면 false를 반환한다. */ 

 }
 catch(Exception e) { e.printStackTrace(); }
 finally { pool.freeConnection(con, pstmt); }
<MemeberDAO.java>

package com.member;

import java.sql.Connection;						// java.sql로 들어왔는지 확인작업 필요
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class MemberDAO {
	// 1. 데이터베이스 연결 ( : 커넥션 풀에서 Connection 객체를 얻는다.)
	// 2. 데이터를 처리 (SQL문을 처리 : 'PreparedStatement', 결과값은 ResultSet 객체가 처리)
	
	// 클래스 영역에서 클래스형으로 레퍼런스 변수 선언을 하면 "의존성 주입(반드시 주입)"의 대상이된다.
	// 인스턴스 변수는 초기화 하지 않는다. "가비지컬렉션"이 자동으로 회수한다.
	private DBConnectionMgr pool;	
	
	// 주입하는 방법은 자바에서 두 가지로 제공한다. 
	// 생성자를 사용하는 방법과 setters 메서드(설정 메서드)를 사용하는 방법이다.
	// 의존성 주입은 생성자를 사용하여 주입한다.
	 public MemberDAO() {
		 // 데이터베이스 연결 객체를 얻는 코드는 필수적으로 예외처리를 한다.
		 try { pool = DBConnectionMgr.getInstance(); }
		 catch(Exception e) {e.printStackTrace();} 	// 예외사항을 디테일하게 콘솔뷰로 출력한다.
	 }
	 
	 public boolean insertMember(MemberVO vo) {
		 Connection con = null;			// import 할때 java.sql 선택해야함
		 PreparedStatement pstmt = null;
		 String sql = null;
		 boolean flag = false;
		 
		 // DB 연결과 데이터 처리는 예외처리를 해야한다.
		 try {
			 con = pool.getConnection(); // 커넥션 풀에서 커넥션 객체 하나를 얻는다.
			 sql = "insert into tblMember (id,pwd,name,gender,birth,email,zipcode,addr,hobby,job,regdate)" + " values (?,?,?,?,?,?,?,?,?,?,now())";
			 pstmt = con.prepareStatement(sql);
			 // 쿼리 실행 객체인 pstmt의 setXxx( ) 메서드로 쿼리문의 위치홀더(?)에 VO의 속성 값을 설정한다.
			 pstmt.setString(1, vo.getId());
			 pstmt.setString(2, vo.getPwd());
			 pstmt.setString(3, vo.getName());
			 pstmt.setString(4, vo.getGender());
			 pstmt.setString(5, vo.getBirth());
			 pstmt.setString(6, vo.getEmail());
			 pstmt.setString(7, vo.getZipcode());
			 pstmt.setString(8, vo.getAddr());
			 
			 // 데이터베이스 컬럼의 셀은 여러개의 값을 저장할 수 없으므로 하나의 값으로 변환하는 작업을 한다.
			 // 체크를 했으면 1을 넣고 체크를 안했으면 0을 넣어서 하나의 값으로 만든다.
			 // 사용자가 인터넷과 게임을 체크하면 '10100'로 하나의 결과값을 만든다.
			 String[] hobby = vo.getHobby();	// 체크한 취미를 얻는다.
			 String[] list = {"인터넷", "여행", "게임", "영화", "운동" };		// 리스트랑 비교해서 있으면 1, 없으면 0
			 // list를 선언한 이유 : hobby 배열과 list 배열을 비교하여 같은 원소가 있으면 1, 없으면 0으로 처리한다.
			 char[] hb = {'0', '0', '0', '0', '0'};
			 
			 // hobby 배열의 원소 하나와 모든 list 배열의 원소들을 비교한다. (비교해서 1,0 처리)
			 for (int i=0; i<hobby.length; i++) {
				 for(int j=0; j<list.length; j++) {
					 if(hobby[i].equals(list[j])) { hb[j] = '1';	 } 	// 만약 사용자가 선택한 취미와 같은 취미가 있으면, 배열 hb에 1을 넣는다.
				 }
			 }
			 pstmt.setString(9, new String(hb));
			 // hb는 char형(문자형) 배열이므로 문자열(문자 배열)로 객체화하여 9번째 위치홀더에 설정한다.
			 
			 pstmt.setString(10, vo.getJob());
			 
			 // 쿼리문을 수행할 때는 executeQuery()와 executeUpdate()가 있다.
			 // executeQuery()는 SELECT 문을 수행할 때 사용하고 executeUpdate()는 INSERT,DELETE문을 수행할 때 사용한다.
			 
		 }
		 catch(Exception e) { e.printStackTrace(); }
		 finally { pool.freeConnection(con, pstmt); } // 사용한 객체를 커넥션 풀로 반납한다.
		 
		 return flag;
	 }
	
	 public boolean checkId(String id) {	// 아이디 중복 체크
			 Connection con = null;		
			 PreparedStatement pstmt = null;
			 ResultSet rs = null;
			 String sql = null;
			 boolean flag = false;
			 try {
				 con = pool.getConnection();
				 sql = "select id from tblMember where id =?";
				 pstmt = con.prepareStatement(sql);
				 pstmt.setString(1, id);
				 flag = pstmt.executeQuery().next();
				 /*flag = rs.next(); 	// next() 는 쿼리문의 실행 결과가 있으면 다음행으로 커서를 옮기며, 다음행이 있으면 true, 없으면 false를 반환한다. */ 
				 
			 }
			 catch(Exception e) { e.printStackTrace(); }
			 finally { pool.freeConnection(con, pstmt); }
		 
		 
		 return flag;
	 }
	 
}

우편번호 검색

<zipCheck.jsp>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.Vector" %>
<%@ page import="com.member.ZipcodeVO" %>

<% request.setCharacterEncoding("utf-8"); %>
<jsp:useBean id="dao" class="com.member.MemberDAO" />

<% 
	String check = request.getParameter("check");
	String area3 = null;
	Vector <ZipcodeVO> vlist = null; 	// vector, zipcodeVO : 임포트를 해줘야함
	// 객체(object=bean)를 여러 개 저장할 때 자료구조 클래스인 'ArrayList' 와 'Vector' 클래스를 사용한다.
	// tblZipcode 테이블에는 42625개의 주소지가 입력되어 있으므로 42625개의 ZipcodeVO로 데이터를 저장한다.
	// 따라서 모든 테이블의 주소지를 가져오려면 42625번의 프로세스를 수행해야한다.
	// 이는 서버 과부화의 원인이 되므로 Vector 클래스를 사용해 한번에 42625개의 주소지를 가져온다.
	// Vector <자료형> 변수명 = new Vector<자료형>();
	
	
	if(check.equals("n")) {// 사용자가 동/면을 입력하고 검색 버튼을 누르면 동/면 값으로 주소지를 검색한다. 
		area3 = request.getParameter("area3"); // == 동을 얻어왔다.
		vlist = dao.zipcodeRead(area3); 	//zipcodeRead : 우편번호 읽기	// dao가 db커넥션한다.
	}
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>우편번호 검색(주소지 검색('동')으로 우편번호 설정)</title> 
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<style>
	a {color:#333; text-decoration:none;}
</style>

<script>
/*
	function dongCheck() {
		if(document.zipFrm.area3 == "") { // area3에 입력값이 없을 경우 (동이름을 넣지 않았을경우)
			alert("동/면 이름을 입력하세요.");
			document.zipFrm.area3.focus();
			return;
		}	
		
		document.zipFrm.action = "zipCheck.jsp"; 	// (동이름을 넣었을경우) 자기 자신 입력폼에 데이터를 전달하도록 한다.
		document.zipFrm.submit();	// submit()으로 전달해라.
	}
	*/
	
	function sendAdd(zipcode, area1, area2, area3, area4) {
		add = area1 + " " + area2 + " " + area3 + " " + area4;		 
		// 우편번호 입력폼에 zipcode 값을 설정하고, 주소 입력 폼에 addr 값을 설정한다.
		// 자식 페이지(=zipCheck.jsp)에서 부모 페이지(=MemberForm.jsp)로 값을 전달할 때는 부모 페이지를 참조 하는 opener를 사용한다.
		console.log(zipcode);
		console.log(add);
		console.log(opener.document);
		
		window.opener.regFrm.zipcode.value = zipcode;
		window.opener.regFrm.addr.value=add;
		
		self.close();
	}
	
	
</script>
</head>
<body>
	<div class="container">
		<!--  부모 페이지 : memberForm.jsp 자식 페이지 : zipCheck.jsp  -->
		<!--  부모/자식 모두 form 페이지가 있기 때문에 name으로 구분해야한다. (name속성이 필요하다) -->
		<form name="zipFrm" action="zipCheck.jsp" method="post"> <!--  옛날방식때문에 action 넣어줌  -->
			<input type="hidden" name="check" value="n"> 
			<!--  검색 버튼을 누른 행위가 check에 n이 있으면 누른것, y가 있으면 누르지 않은것 -->
			<!--  type=:hidden"은 웹 브라우저 상에 보이지 않으면서 어떤 변수에 값을 넣어서 전달해주고 싶을떄 사용 -->
			<!-- 검색 버튼을 누르면 check 변수에 'n' 값을 저장한 후 전달한다. -->
			
			<table class="table">
				<tr>
					<td>
						동/면 이름 입력 : <input type="text" name="area3" autofocus required>	<!-- value="" : 아무것도 입력안하면 null값을 넣어주겠다.  : 얫날방식이라 빼줌  -->
						<input type="submit" value="검색">	
						<!-- type="button" : 옛방식이라 submit으로 변경함 --><!--  onClick="dongCheck()" : 옛방식이라 빼줌 --> <!-- 검색 버튼 누르면 dongcheck 함수를 불러온다. --> 
					</td>
				</tr>
<%
	if(check.equals("n")) {	// 동/면 을 입력하고 검색 버튼을 누르면
		if(vlist.isEmpty()) {	// vlist에 zipcodeVO 객체가 없으면(주소가 없으면) 
%>
			<tr><td>검색된 결과가 없습니다.</td></tr>
<%
		} else {		// 검색된 결과가 있을 때 (주소가 있으면)
%>
				<tr><td>※ 아래 우편번호를 클릭하면 주소지가 자동으로 입력됩니다. </td></tr>
<%
			//  Vector 클래스는 객체(zvo)에 인덱스 번호를 지정하여 관리한다.
			for(int i=0; i<vlist.size(); i++) {		// Vector 클래스는 size()로 크기를 얻는다.
				ZipcodeVO zvo = vlist.get(i);
				// Vector에 있는 ZipcodeVO의 객체를 인덱스 번호로 하나씩 순차적으로 얻어온다.
				String dzipcode = zvo.getZipcode();
				String dArea1 = zvo.getArea1();
				String dArea2 = zvo.getArea2();
				String dArea3 = zvo.getArea3(); // 오류 발생 이유 : 위쪽에서 '동= area3'를 가져와 선언할 때 이미 String으로 변수선언을 해줬기 때문에 DB에서 가져왔다는 d를 붙여줌
				String dArea4 = zvo.getArea4();
			
%>
				<tr>
					<td><a href="#" onClick="javascript:sendAdd('<%= dzipcode %>','<%= dArea1 %>','<%= dArea2 %>','<%= dArea3 %>','<%= dArea4 %>')"><%= dzipcode %></a></td>	/<!--  dzipcode를 선택했을 떄 sendAdd() 함수를 호출하겠다.  -->
					<td><%= dArea1 %></td>	
					<td><%= dArea2 %></td>	
					<td><%= dArea3 %></td>	
					<td><%= dArea4 %></td>	
				</tr>
<%
			}	// for-end
		}	// else-end
	} // if-end
%>			
				<tr><td><a href="#" onClick="self.close()">닫기</a></td></tr>
			</table>
		</form>
	</div>	
</body>
</html>

 

<ZipcodeVO.java>

package com.member;

public class ZipcodeVO {
	private String zipcode;
	private String area1; 
	private String area2; 
	private String area3; 
	private String area4;
	
	public String getZipcode() {
		return zipcode;
	}
	public void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}
	public String getArea1() {
		return area1;
	}
	public void setArea1(String area1) {
		this.area1 = area1;
	}
	public String getArea2() {
		return area2;
	}
	public void setArea2(String area2) {
		this.area2 = area2;
	}
	public String getArea3() {
		return area3;
	}
	public void setArea3(String area3) {
		this.area3 = area3;
	}
	public String getArea4() {
		return area4;
	}
	public void setArea4(String area4) {
		this.area4 = area4;
	} 
}

 

<MemberDAO.java>

package com.member;

import java.sql.Connection;						// java.sql로 들어왔는지 확인작업 필요
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Vector;

public class MemberDAO {
	// 1. 데이터베이스 연결 ( : 커넥션 풀에서 Connection 객체를 얻는다.)
	// 2. 데이터를 처리 (SQL문을 처리 : 'PreparedStatement', 결과값은 ResultSet 객체가 처리)
	
	// 클래스 영역에서 클래스형으로 레퍼런스 변수 선언을 하면 "의존성 주입(반드시 주입)"의 대상이된다.
	// 인스턴스 변수는 초기화 하지 않는다. "가비지컬렉션"이 자동으로 회수한다.
	private DBConnectionMgr pool;	
	
	// 주입하는 방법은 자바에서 두 가지로 제공한다. 
	// 생성자를 사용하는 방법과 setters 메서드(설정 메서드)를 사용하는 방법이다.
	// 의존성 주입은 생성자를 사용하여 주입한다.
	 public MemberDAO() {
		 // 데이터베이스 연결 객체를 얻는 코드는 필수적으로 예외처리를 한다.
		 try { pool = DBConnectionMgr.getInstance(); }
		 catch(Exception e) {e.printStackTrace();} 	// 예외사항을 디테일하게 콘솔뷰로 출력한다.
	 }
	 
	 public boolean insertMember(MemberVO vo) {
		 Connection con = null;			// import 할때 java.sql 선택해야함
		 PreparedStatement pstmt = null;
		 String sql = null;
		 boolean flag = false;
		 
		 // DB 연결과 데이터 처리는 예외처리를 해야한다.
		 try {
			 con = pool.getConnection(); // 커넥션 풀에서 커넥션 객체 하나를 얻는다.
			 sql = "insert into tblMember (id,pwd,name,gender,birth,email,zipcode,addr,hobby,job,regdate)" + " values (?,?,?,?,?,?,?,?,?,?,now())";
			 pstmt = con.prepareStatement(sql);
			 // 쿼리 실행 객체인 pstmt의 setXxx( ) 메서드로 쿼리문의 위치홀더(?)에 VO의 속성 값을 설정한다.
			 pstmt.setString(1, vo.getId());
			 pstmt.setString(2, vo.getPwd());
			 pstmt.setString(3, vo.getName());
			 pstmt.setString(4, vo.getGender());
			 pstmt.setString(5, vo.getBirth());
			 pstmt.setString(6, vo.getEmail());
			 pstmt.setString(7, vo.getZipcode());
			 pstmt.setString(8, vo.getAddr());
			 
			 // 데이터베이스 컬럼의 셀은 여러개의 값을 저장할 수 없으므로 하나의 값으로 변환하는 작업을 한다.
			 // 체크를 했으면 1을 넣고 체크를 안했으면 0을 넣어서 하나의 값으로 만든다.
			 // 사용자가 인터넷과 게임을 체크하면 '10100'로 하나의 결과값을 만든다.
			 String[] hobby = vo.getHobby();	// 체크한 취미를 얻는다.
			 String[] list = {"인터넷", "여행", "게임", "영화", "운동" };		// 리스트랑 비교해서 있으면 1, 없으면 0
			 // list를 선언한 이유 : hobby 배열과 list 배열을 비교하여 같은 원소가 있으면 1, 없으면 0으로 처리한다.
			 char[] hb = {'0', '0', '0', '0', '0'};
			 
			 // hobby 배열의 원소 하나와 모든 list 배열의 원소들을 비교한다. (비교해서 1,0 처리)
			 for (int i=0; i<hobby.length; i++) {
				 for(int j=0; j<list.length; j++) {
					 if(hobby[i].equals(list[j])) { hb[j] = '1';	 } 	// 만약 사용자가 선택한 취미와 같은 취미가 있으면, 배열 hb에 1을 넣는다.
				 }
			 }
			 pstmt.setString(9, new String(hb));
			 // hb는 char형(문자형) 배열이므로 문자열(문자 배열)로 객체화하여 9번째 위치홀더에 설정한다.
			 
			 pstmt.setString(10, vo.getJob());
			 
			 // 쿼리문을 수행할 때는 executeQuery()와 executeUpdate()가 있다.
			 // executeQuery()는 SELECT 문을 수행할 때 사용하고 executeUpdate()는 INSERT,DELETE문을 수행할 때 사용한다.
			 
		 }
		 catch(Exception e) { e.printStackTrace(); }
		 finally { pool.freeConnection(con, pstmt); } // 사용한 객체를 커넥션 풀로 반납한다.
		 
		 return flag;
	 }
	
	 public boolean checkId(String id) {	// 아이디 중복 체크
			 Connection con = null;		
			 PreparedStatement pstmt = null;
			 ResultSet rs = null;
			 String sql = null;
			 boolean flag = false;
			 try {
				 con = pool.getConnection();
				 sql = "select id from tblMember where id =?";
				 pstmt = con.prepareStatement(sql);
				 pstmt.setString(1, id);
				 flag = pstmt.executeQuery().next();
				 /*flag = rs.next(); 	// next() 는 쿼리문의 실행 결과가 있으면 다음행으로 커서를 옮기며, 다음행이 있으면 true, 없으면 false를 반환한다. */ 
				 
			 }
			 catch(Exception e) { e.printStackTrace(); }
			 finally { pool.freeConnection(con, pstmt); }
		 
		 
		 return flag;
	 }
	 
	 public Vector <ZipcodeVO> zipcodeRead(String area3) {
		 Connection con = null;		
		 PreparedStatement pstmt = null;
		 ResultSet rs = null;
		 String sql = null;
		 Vector <ZipcodeVO> vlist = new Vector<ZipcodeVO>();
		 
		 try {
			 con = pool.getConnection();
			 sql = "select * from tblZipcode where area3 like ?";
			 pstmt = con.prepareStatement(sql);
			 pstmt.setString(1, "%"+area3+"%");
			 rs = pstmt.executeQuery();	// rs는 DB에서 얻어 온 데이터를 저장한다.
			 // rs에 있는 데이터를 행 단위로 ZipcodeVO에 설정한다.
			 while(rs.next()) {	// 테이블에 행이 있으면 반복 수행한다.
				 ZipcodeVO zvo = new ZipcodeVO();
				 zvo.setZipcode(rs.getString(1));
				 zvo.setArea1(rs.getString(2));
				 zvo.setArea2(rs.getString(3));
				 zvo.setArea3(rs.getString(4));
				 zvo.setArea4(rs.getString(5));
				 
				 vlist.add(zvo); 	// Vector에 ZipcodeVO를 추가한다. Vector는 가변적인 크기를 가진다.
			 }
			 
		 }
		 catch(Exception e) { e.printStackTrace(); }
		 finally { pool.freeConnection(con, pstmt); }
	 
		 return vlist;
	 }
	 
	 
	 
}

'국비지원 JAVA 풀스택 과정 > JAVA' 카테고리의 다른 글

[JSP] 오류발생  (1) 2022.12.15
[JSP] 회원관리 프로그램2  (0) 2022.12.13
[JSP] 회원관리 프로그램  (0) 2022.12.12
[JAVA] 파일 업로드 구현  (0) 2022.12.09
[JAVA] 자동 줄바꿈 처리  (0) 2022.12.09