<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 |