국비 31

냐아암·2023년 5월 30일
0

국비

목록 보기
44/114

Member 게시판 만들기


MemberRun

package edu.kh.jdbc.run;

import edu.kh.jdbc.main.view.MainView;

public class ProjectRun {

	public static void main(String[] args) {
		
		MainView view = new MainView();
		
		view.displayMenu();
		
		

	}

}

MainView

package edu.kh.jdbc.main.view;

import java.util.InputMismatchException;
import java.util.Scanner;

import edu.kh.jdbc.board.view.BoardView;
import edu.kh.jdbc.member.model.vo.Member;
import edu.kh.jdbc.member.view.MemberView;

public class MainView { // 메인 메뉴(메뉴 선택용/입력 화면)
	
	private Scanner sc = new Scanner(System.in);
	
	// 로그인한 회원의 정보가 저장된 객체를 참조할 변수
	private Member loginMember = null;
	
	// 회원 관련 기능 화면을 모아둔 객체를 참조할 변수
	private MemberView memberView = new MemberView();
	
	// 게시판 관련 기능 화면을 모아둔 객체를 참조할 변수
	private BoardView boardView = new BoardView();
	
	/**
	 *  메인메뉴 출력 메소드
	 */
	public void displayMenu() {
		
		int menuNum = -1; // 메뉴 선택 값 저장 변수
		// 초기값을 -1로 지정하여 반복문 첫 바퀴에서 오류 발생 시 종료되는 것을 방지
		
		do {
			
			try {
				
				if (loginMember == null) { // 로그인이 되어있지 않은 경우
					
					System.out.println("\n******** 회원제 게시판 프로그램 ********\n");
					
					System.out.println("1. 로그인");
					System.out.println("2. 회원가입");
					System.out.println("0. 프로그램 종료");
					
					System.out.print("메뉴를 선택해주세요 >> ");
					
					menuNum = sc.nextInt(); // InputMismatchException
					sc.nextLine(); // 입력 버퍼에 남아있는 개행 문자 제거
					
					System.out.println(); // 줄바꿈
					
					switch(menuNum) {
					case 1: loginMember = memberView.login(); break;
					case 2: memberView.signUp(); break;
					case 0: System.out.println("---- 프로그램 종료 ----"); break;
					default: System.out.println("메뉴에 작성된 번호를 입력해주세요.");
					}
					
				} else { // 로그인이 되어있는 경우
					
					System.out.println("\n******** 회원 메뉴 ********\n");
					// - 로그인한 회원 정보 조회
					// - 회원 목록 조회
					// - 회원 정보 수정(이름, 성별)
					// - 비밀번호 변경
					// - 회원 탈퇴
					System.out.println("1. 내 정보 조회");
					System.out.println("2. 가입된 회원 목록 조회");
					System.out.println("3. 내 정보 수정(이름, 성별)");
					System.out.println("4. 비밀번호 변경");
					System.out.println("5. 회원 탈퇴");
					
					System.out.println("6. * 게시판 메뉴 화면 *");
					
					System.out.println("9. 로그아웃");
					System.out.print("메뉴를 선택해주세요 >> ");
					menuNum = sc.nextInt();
					sc.nextLine();
					
					switch(menuNum) {
					case 1: memberView.myInfo(loginMember); break;
					case 2: memberView.selectAll(); break;
					case 3: memberView.updateMyInfo(loginMember); break;
					case 4: memberView.updatePw(loginMember); break;
					case 5: 
						int result = memberView.secession(loginMember); 
						if(result > 0) loginMember = null; //로그아웃
						break;
						
					case 6: boardView.boardMenu(loginMember); break;
					case 9: loginMember = null; break;
					default: System.out.println("메뉴에 작성된 번호를 입력해주세요.");
					}
					
				}
				
			} catch ( InputMismatchException e) {
				System.out.println("\n입력 형식이 올바르지 않습니다. 다시 시도해주세요.");
				sc.nextLine(); // 입력 버퍼에 남은 잘못 입력된 문자열 제거
			}
			
		} while(menuNum != 0);
		
	}

}

MemberView

package edu.kh.jdbc.member.view;

import java.util.List;
import java.util.Scanner;

import edu.kh.jdbc.member.model.service.MemberService;
import edu.kh.jdbc.member.model.vo.Member;

public class MemberView { // 회원 관련 화면 입출력

	private Scanner sc = new Scanner(System.in);
	
	// 회원 관련 서비스 제공 객체 생성 및 참조
	private MemberService service = new MemberService();
	
	
	/**
	 * 회원 가입 화면 출력용 메소드
	 */
	public void signUp() { 
		
		System.out.println("[회원 가입]");
		
		try {
			
			String memberId = null;
			String memberPw = null;
			String memberPw2 = null;
			String memberName = null;
			char memberGender = ' ';
			
			while(true) { // 중복 아이디가 없을 경우 종료하는 if문 필요
				System.out.print("아이디: ");
				memberId = sc.next();
				
				/* 아이디 중복 검사 (DB에 일치하는 아이디가 있으면 "중복" -> 다시 아이디 입력받기 */
				
				int result = service.duplicateCheck(memberId);
				// result는 중복이면 1, 아니면 0 반환될 예정
				
				if(result == 0) { // 중복이 아니면 반복문 종료
					System.out.println("사용 가능한 아이디입니다.");
					break;
					
				} else {
					System.out.println("[이미 사용 중인 아이디입니다. 다시 입력해주세요.]");
				}
				
			} // 중복 검사 while문 종료
			
			// 비밀번호, 비밀번호 확인을 각각 입력받아 
			// 일치할 때까지 무한반복
			
			
			while(true) {
				
				System.out.print("비밀번호 입력: ");
				memberPw = sc.next();
				
				System.out.print("비밀번호 확인: ");
				memberPw2 = sc.next();
				
				if(memberPw.equals(memberPw2)) { // 일치하면
					break;
				} else {
					System.out.println("\n비밀번호가 일치하지 않습니다. 다시 입력해주세요.\n");
				}
				
			} // 비밀번호 확인 while문 종료
			
			// 이름 입력
			System.out.print("회원 이름: ");
			memberName = sc.next();
			
			// 성별이 'M' 또는 'F'가 입력될 때까지 반복
			while(true) {
				
				System.out.print("성별 입력(M/F): ");
				memberGender = sc.next().toUpperCase().charAt(0);
				//String.toUpperCase(): 문자열을 대문자로 변환
				
//				if(memberGender != 'M' && memberGender != 'F') {
//					System.out.println("\n[성별은 M또는 F만 입력해주세요]\n");
//				} else {
//					break;
//				}
				
				
				if(memberGender == 'M' || memberGender == 'F') {
					break;
				} else {
					System.out.println("\n[성별은 M또는 F만 입력해주세요]\n");
				}
		
			} // 성별 while문 종료
			
			// 입력 받은 값을 하나의 객체(Member)에 저장
			Member signUpMember = new Member(memberId, memberPw, memberName, memberGender);
		
			// 회원가입 Service 호출 후 결과 반환 받기
			// - 회원가입 == DB에 회원 정보 삽입 == INSERT(DML)
			// -> DML구문 수행 시 성공한 행의 개수 반환됨 == int형 변수로 결과를 저장
			
			int result = service.signUp(signUpMember);
			
			// Service 결과에 따른 화면 처리
			if(result > 0) { // 가입 성공
				System.out.println("\n*** 회원 가입 성공 ***\n");
			} else {
				System.out.println("[회원 가입 실패]");
			}
			
		} catch (Exception e) {
			System.out.println("\n<회원가입 중 예외 발생>\n");
			e.printStackTrace(); // 예외 내용 출력
		}
		
		
		
		
	}


	/** 로그인 메소드
	 * @return
	 */
	public Member login() {
		
		System.out.println("[로그인]");
		
		System.out.print("아이디: ");
		String memberId = sc.next();
		
		System.out.print("비밀번호: ");
		String memberPw = sc.next();
		
		// Member 객체 생성해서 입력받은 값 세팅
		Member mem = new Member();
		
		mem.setMemberId(memberId); // setter 이용해서 초기화
		mem.setMemberPw(memberPw);
		
		// 로그인 Service 수행 후 결과 반환 받기
		Member loginMember = null;
		
		try {
			loginMember = service.login(mem);
			
			if(loginMember != null) { // 참조하는 객체가 있다 == 로그인 성공
				System.out.println("\n*** " + loginMember.getMemberName()+ " 님 환영합니다. ***\n");
				
			} else { // 로그인 실패(아이디 또는 비밀번호 불일치 또는 탈퇴한 회원
				
				System.out.println("\n[아이디 또는 비밀번호가 일치하지 않습니다.]\n");
			}
			
		} catch (Exception e) {
			System.out.println("\n로그인 과정에서 예외 발생\n");
			e.printStackTrace();
		}
		
		return loginMember;
	}


	/** 내 정보 조회 
	 * @param loginMember
	 */
	public void myInfo(Member loginMember) {
		
		System.out.println("[내 정보 조회]");
		
		System.out.println("회원 번호: " + loginMember.getMemberNo());
		System.out.println("아이디: " + loginMember.getMemberId());
		System.out.println("이름: " + loginMember.getMemberName());
		if (loginMember.getMemberGender() == 'F') System.out.println("성별: 여성");
		else									  System.out.println("성별: 남성");
		System.out.println("가입일: " + loginMember.getEnrollDate());
		
	}


	/**
	 * 회원 목록 조회
	 */
	public void selectAll() {

		System.out.println("[가입된 회원 목록 조회]");
		
		// DB에서 회원 정보 모두 조회(아이디, 이름, 가입일)
		// 단, 탈퇴 회원 제외, 아이디 오름차순 조회
		
		try {
			
			// 회원정보 조회 Service 호출 후 결과 반환받기
			List<Member> memberList = service.selectAll();
			
			if(memberList.isEmpty()) { // 비어있음 == 조회 결과 없음
				
				System.out.println("조회 결과가 없습니다.");
				
			} else {
				
				// 향상된 for문 사용
				for(Member m : memberList) {
					System.out.printf("%12s   %12s   %s\n",
										m.getMemberId(), m.getMemberName(), 
										m.getEnrollDate().toString());
				}
			}
			
			
			
		} catch (Exception e) {
			System.out.println("\n<회원 목록 조회 과정에서 예외 발생>\n");
			e.printStackTrace();
		}
		
	}


	/** 내 정보 수정
	 * @param loginMember
	 */
	public void updateMyInfo(Member loginMember) {
		
		System.out.println("[내 정보 수정(이름, 성별)]");
		
		System.out.print("변경할 이름: ");
		String memberName = sc.next();
		
		System.out.print("변경할 성별(M/F): ");
		char memberGender = sc.next().toUpperCase().charAt(0);
		
		// 입력받은 값 + 로그인한 회원 번호 하나의 Member 객체에 저장
		// 로그인한 회원 번호 == 어떤 회원 정보를 수정할지 지정
		Member updateMember = new Member();
		
		updateMember.setMemberName(memberName);
		updateMember.setMemberGender(memberGender);
		updateMember.setMemberNo(loginMember.getMemberNo());
		
		
		try {
			
			// UPDATE == DML == 수행 성공한 결과 행의 개수를 반환 == 정수형
			int result = service.updateMyInfo(updateMember);
			
			if (result > 0) {
				// 수정 성공 + loginMember 바꾸기
				System.out.println("\n[회원 정보가 수정되었습니다.]");
				
				// DB에 수정된 내용과 현재 로그인한 회원 정보를 일치시킴
				// 얕은 복사: 참조 주소만 복사하여 같은 객체를 참조
				// -> 특징: 복사된 주소를 참조하여 수정하면 원본 객체가 수정된다.
				loginMember.setMemberName(memberName);
				loginMember.setMemberGender(memberGender);
				
			} else {
				// 수정 실패
				System.out.println("\n[회원 정보 수정에 실패했습니다.]");
			}
			
		} catch (Exception e) {
			System.out.println("\n<내 정보 수정 과정에서 예외 발생>\n");
		}
		
		// 수정한 값으로 loginMember에 있는 값까지 바꾸세요(DB만 바꾸지 말고)
		
		
	}


	/** 비밀번호 변경
	 * @param loginMember
	 */
	public void updatePw(Member loginMember) {
		

	      System.out.println("[비밀번호 변경]");
	      
	      // 현재 비밀번호 --> DB Update 조건(WHERE)
	      System.out.print("현재 비밀번호 :");
	      String currentPw = sc.next();
	      
	      String newPw = null;
	      String newPw2 = null;
	   
	      while(true) {
	         // 새 비밀번호
	         System.out.print("새 비밀번호 : ");
	          newPw = sc.next();
	         
	          // -> 둘이 일치할 뗴 까지 무한 반복
	         // 새 비밀번호 확인
	         System.out.print("새 비밀번호 확인 : ");
	          newPw2 = sc.next();
	         
	         // 변경할 비밀번호가 일치한지 비교
	         if(newPw.equals(newPw2) ) {
	            break;
	         }else {
	            System.out.println("\n새 비밀번호가 일치하지 않습니다. 다시 입력해주세요.\n");
	         }
	         
	      }
	      
	      try {
	         int result = service.updatePw(loginMember.getMemberNo(), currentPw, newPw);

	         // 성공 : "[비밀번호가 변경되었습니다]"
	         // 실패 : "[비밀번호가 일치하지 않습니다.]"
	         if(result > 0 ) {
	         System.out.println("[비밀번호가 변경되었습니다]");
	         
	         }else {
	            System.out.println("[비밀번호가 일치하지 않습니다.]");
	         }
	         
	      }catch(Exception e) {
	         System.out.println("\n<비밀번호 변경 중 예외 발생>\n");
	         e.printStackTrace();
	      }
		
		
	}


	/** 회원 탈퇴 View
	 * @param loginMember
	 */
	public int secession(Member loginMember) {
		// loginMember = null;
		// -> 매개변수로 전달받은 값(주소 복사본)을 저장할 뿐이다.
		// -> 복사본이 사라진다고 해도 원본(MainView의 loginMember)은 사라지지 않는다. == 로그아웃이 안 됨
		System.out.println("[회원 탈퇴]");
		
		// 1. 현재 비밀번호 입력 받기
		System.out.print("비밀번호 입력: ");
		String memberPw = sc.next();
		
		// 2. 정말 탈퇴하시겠습니까? (Y/N)
		System.out.print("정말 탈퇴하시겠습니까? (Y/N): ");
		char ch = sc.next().toUpperCase().charAt(0);
		
		
		
		try {
			// 3. (Y 입력 시 탈퇴 Service 수행)
			if(ch == 'Y') {
				// 로그인한 회원 번호 + 입력받은 비밀번호
				int result = service.secession(loginMember.getMemberNo(), memberPw);
				
				if (result > 0) {
					System.out.println("탈퇴되었습니다.");
					
					return result; // 현재 메소드를 종료하고 호출한 곳으로 돌아감
					
				} else {
					System.out.println("비밀번호가 일치하지 않습니다.");
				}
				
				
				// 4. 탈퇴 Service 수행 성공 -> "탈퇴 되었습니다." --> 로그아웃
				//	  탈퇴 Service 수행 실패 -> "비밀번호가 일치하지 않습니다."
			}else {
				// (N 입력 시) "회원 탈퇴 취소"
				System.out.println("\n[회원 탈퇴 취소]\n");
				
			}
			
			
		} catch (Exception e) {
			System.out.println("\n회원 탈퇴 과정에서 예외 발생\n");
			e.printStackTrace();
		}
		
		return 0;
		
		
	}

}

MemberService

package edu.kh.jdbc.member.model.service;

// import static 구문: static 메소드를 import 하여
//					  클래스명.static 메소드() 형태에서 
//					  클래스명을 생략할 수 있게 하는 구문

import static edu.kh.jdbc.common.JDBCTemplate.getConnection;
import static edu.kh.jdbc.common.JDBCTemplate.close;
import static edu.kh.jdbc.common.JDBCTemplate.commit;
import static edu.kh.jdbc.common.JDBCTemplate.rollback;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import edu.kh.jdbc.common.JDBCTemplate;
import edu.kh.jdbc.member.model.dao.MemberDAO;
import edu.kh.jdbc.member.model.vo.Member;

// Service : 데이터 가공(요청에 맞는 데이터를 만드는 것)
//			+ 트랜잭션 제어 처리
//			-> 하나의 Service 메소드에서 n개의 DAO 메소드를 호출할 수 있다.
//				-> n개의 DAO에서 수행된 SQL을 한 번에 commit / rollback

// *** Service에서 트랜잭션을 처리하기 위해서는 Connection 객체가 필요하다 ***
//		== Service에서 Connection 객체를 생성하고 반환해야 한다.

public class MemberService {

	// 회원 관련 SQL 수행 및 결과를 반환할 DAO 객체 생성 및 참조
	private MemberDAO dao = new MemberDAO();
	
	/** 아이디 중복 검사 Service
	 * @param memberId
	 * @return
	 * @throws Exception 
	 */
	public int duplicateCheck(String memberId) throws Exception {
		
		// 1. Connection 객체 생성
		// -> JDBCTemplate에 작성된 getConnection() 메소드를 이용해 생성 후 얻어옴
		Connection conn = getConnection(); // JDBCTemplate.getConnection()
		
		// 2. DAO 메소드 (SELECT) 호출 후 결과 반환 받음
		int result = dao.duplicateCheck(conn, memberId);
		// (SELECT는 별도의 트랜잭션 제어 필요 없음)
		// 3. 사용한 Connection 객체 반환
		close(conn);
		
		// 4. 중복 검사 결과 View로 반환
		
		
		return result;
	}

	/** 회원가입 Service
	 * @param signUpMember
	 * @return result
	 * @throws Exception
	 */
	public int signUp(Member signUpMember) throws Exception { // 모든 예외는 View에서 모아 처리
		
		// 1) Connection 생성
		Connection conn = getConnection(); // 위에 import 해놔서 클래스명. 생략
		
		// 2) 회원가입 DAO 메소드 호출하고 결과 반환 받기
		int result = dao.signUp(conn, signUpMember); // 커넥션도 같이 보내줘야 함
		
		// 3) DAO 수행 결과에 따라 트랜잭션 처리
		if(result > 0) commit(conn);
		else		   rollback(conn);
		
		// 4) 사용한 Connection 반환
		close(conn);
		
		// 5) DAO 수행 결과 View로 반환
		return result;
	}

	/** 로그인 Service
	 * @param mem
	 * @return loginMember
	 * @throws Exception
	 */
	public Member login(Member mem) throws Exception {
		
		// 1) Connection 생성
		Connection conn = getConnection();
		
		// 2) DAO 메소드 수행 후 결과 반환 받기
		Member loginMember = dao.login(conn, mem);
		
		// (SELECT 수행 -> 트랜잭션 제어 처리 X)
		
		// 3) Connection 반환
		close(conn);
		
		// 4) DAO 조회 결과 View로 반환
		return loginMember;
	}

	/** 가입된 회원의 목록을 조회하는 Service
	 * @return memberList
	 * @throws Exception
	 */
	public List<Member> selectAll() throws Exception {
		
		// 1) Connection 생성 (트랜잭션 제어용)
		Connection conn  = getConnection();
		
		// 2) DAO 메소드(SELECT 수행) 호출 후 결과 반환받기
		List<Member> memberList = dao.selectAll(conn);
		
		// 3) Connection 반환
		close(conn);
		
		// 4) DAO 호출 결과 View로 반환
		return memberList;
	}

	/** 내 정보 수정 Service
	 * @param updateMember
	 * @return result
	 * @throws Exception
	 */
	public int updateMyInfo(Member updateMember) throws Exception {
		
		// 1) Connection 생성
		Connection conn = getConnection();
		
		// 2) DAO 수행 (UPDATE 후 결과 반환)
		
		int result = dao.updateMyInfo(conn, updateMember);
		
		// 3) 트랜잭션 제어 처리 (DML 사용했기 때문)
		if(result > 0) commit(conn);
		else		   rollback(conn);
		
		// 4) Connection 반환 
		close(conn);
		
		// 5) DAO 호출 결과를 View로 반환
		return result;
	}

	 /** 비밀번호 변경 Service
	    * @param memberNo
	    * @param currentPw
	    * @param newPw
	    * @return result
	    * @throws Exception
	    */
	   public int updatePw(int memberNo, String currentPw, String newPw) throws Exception{
	      // 1) Connection 생성
	      Connection conn = getConnection();
	      
	      // 2) DAO 수행(UPDATE) 후 결과 반환 받기
	      int result = dao.updatePw(conn, memberNo, currentPw, newPw);
	      
	      // 3) 트랜잭션 제어 처리
	      if(result > 0) commit(conn);
	      else           rollback(conn);
	      
	      // 4) Connection 반환
	      close(conn);
	      
	      // 5) DAO 수행 결과를 View로 반환
	      
	      return result;
	   }

	   
	   
	/** 회원 탈퇴 Service
	 * @param memberNo
	 * @param memberPw
	 * @return result
	 * @throws Exception
	 */
	public int secession(int memberNo, String memberPw) throws Exception {
		
		// 1. Connection
		Connection conn = getConnection();
		
		// 2. DAO 수행
		int result = dao.secession(conn, memberNo, memberPw);
		
		// 3) 트랜잭션 제어 처리
		if (result > 0) commit(conn);
		else			rollback(conn);
		
		// 4) Connection 반환
		close(conn);
		
		return result;
	}

}

MemberDAO

package edu.kh.jdbc.member.model.dao;

import static edu.kh.jdbc.common.JDBCTemplate.close;

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import edu.kh.jdbc.member.model.vo.Member;

// DAO (Data Access Object): 데이터가 저장되어 있는 DB, 파일 등에 접근하는 객체
//							-> DB 접근할 수 있다 == SQL을 수행하고 결과를 반환받을 수 있다.

// Java에서 DB에 접근하고 결과를 반환받기 위한 프로그래밍 APQ 제공함
// == JDBC(Connection, Statement, PreparedStatement, ResultSet)

public class MemberDAO {
	
	private Statement stmt;
	private PreparedStatement pstmt;
	private ResultSet rs = null;
	
	private Properties prop = null;
	// Map인데 K, V 모두 String, 외부 XML 파일 입출력 특화
	
	// Member DAO 기본 생성자
	public MemberDAO() { // MemberDAO 객체 생성 동시에 생성자 실행됨
		// MemberDAO 객체 생성 시
		// member-sql.xml 파일 내용을 읽어와
		// Properties 객체 생성
		try {
			prop = new Properties();
			prop.loadFromXML(new FileInputStream("member-sql.xml"));
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	

	/** 아이디 중복 검사 DAO 메소드
	 * @param conn
	 * @param memberId
	 * @return result
	 * @throws Exception
	 */
	public int duplicateCheck(Connection conn, String memberId) throws Exception {
		// throws: 호출한 메소드로 예외 던짐
		
		// 1) 결과 저장용 변수
		int result = 0;
		
		try {
			
			// 2) SQL 작성
			String sql = "SELECT COUNT(*) FROM MEMBER WHERE MEMBER_ID = ? AND SECESSION_FL='N'";
			
			// 3) PreparedStatement 객체 생성(Connection, SQL 필요)
			pstmt = conn.prepareStatement(sql);
			
			// 4) 위치홀더 '?'에 알맞은 값 세팅
			pstmt.setString(1, memberId);
		
			// 5) SQL 수행 후 결과 반환받기
			rs = pstmt.executeQuery(); // SELECT 수행 결과 ResultSet 반환 받음
			
			// 5) 조회 결과를 한 행씩 접근하여 원하는 컬럼 값 얻어오기
			// -> 아이디 중복 검사 SELECT 결과는 0 또는 1이라는 1행 결과가 무조건 나옴
			// -> while문보다 if문을 사용하는 게 효과적
			
			if(rs.next()) {
				
//				result = rs.getInt("COUNT(*)");
				result = rs.getInt(1);  // 1은 컬럼순서 (위 코드와 동일한 내용)
				
			}
			
		} finally { // try finally 구문 (catch는 throws에 의해 생략)
			// 7) 사용한 JDBC 자원 반환 (conn 제외 -> 서비스에서 또 써야 하니까)
			close(rs);
			close(pstmt);
			
		}
		
		// 8) SQL 수행 결과 반환
		return result;
	}

	/** 회원가입 DAO
	 * @param conn
	 * @param signUpMember
	 * @return result
	 * @throws Exception
	 */
	public int signUp(Connection conn, Member signUpMember) throws Exception {
		
		int result = 0; // 결과 저장용 변수
		
		try {
			
			// 1) SQL 작성 (Properties에 저장된 SQL 얻어오기)
			String sql = prop.getProperty("signUp"); // key값 작성 -> value 얻어옴
			
			// 2) PreparedStatement 객체 생성 (Connection, SQL 필요)
			pstmt = conn.prepareStatement(sql);
			
			// 3) 위치홀더 '?'에 알맞은 값 세팅
			pstmt.setString(1, signUpMember.getMemberId());
			pstmt.setString(2, signUpMember.getMemberPw());
			pstmt.setString(3, signUpMember.getMemberName());
			pstmt.setString(4, signUpMember.getMemberGender() + "");
			// getMemberGender() 의 반환형은 char
			// SetString() 의 매개변수는 String
			// -> 자료형 불일치로 오류 발생
			
			// --> char 자료형 + ""(빈 문자열) == 문자열
			// 1 + 1 = 2
			
			// 1 + "1" = 11
			
			// 4) SQL(INSERT) 수행 후 결과 반환 받기
			result = pstmt.executeUpdate(); // 성공한 행의 개수 반환
			
		} finally {
			// 5) 사용한 JDBC 자원 반환 (Connection 제외)
			close(pstmt);
		}
		
		return result;
	}


	/** 로그인 DAO
	 * @param conn
	 * @param mem
	 * @return loginMember
	 * @throws Exception
	 */
	public Member login(Connection conn, Member mem) throws Exception {
		
		// 결과 저장용 변수 선언
		Member loginMember = null;
		
		try {
			
			// 1) SQL 작성 (Properties에서 얻어오기)
			String sql = prop.getProperty("login");
			
			// 2) PreparedStatement 생성
			pstmt = conn.prepareStatement(sql);
			
			// 3) 위치홀더 '?'에 알맞은 값 세팅
			pstmt.setString(1, mem.getMemberId());
			pstmt.setString(2, mem.getMemberPw());
			
			// 4) SQL(SELECT) 수행 후 결과(ResultSet) 반환받기(rs 변수 사용)
			rs = pstmt.executeQuery();
			
			// 5) if 또는 while 이용해서 rs에 한 행씩 접근해서 원하는 값 얻어오기
			if(rs.next()) {
				
				int memberNo = rs.getInt("MEMBER_NO");
				String memberId = rs.getString("MEMBER_ID");
				String memberName = rs.getString("MEMBER_NM");
				char memberGender = rs.getString("MEMBER_GENDER").charAt(0);
				Date enrollDate = rs.getDate("ENROLL_DATE");
				
				// 6) 얻어온 컬럼 값을 이용해서 Member 객체 생성하여 loginMember 변수에 저장
				loginMember = new Member();
				
				loginMember.setMemberNo(memberNo);
				loginMember.setMemberId(memberId);
				loginMember.setMemberName(memberName);
				loginMember.setMemberGender(memberGender);
				loginMember.setEnrollDate(enrollDate);
				
			}
			
		} finally {
			
			// ) 사용한 JDBC 자원 반납 (Connection 제외)
			rs.close();
			close(pstmt);
			
		}
		
		// 8) DAO 수행 결과 반환
		return loginMember;
	}




	/** 가입된 회원 목록 조회 DAO
	 * @param conn
	 * @return memberList
	 * @throws Exception
	 */
	public List<Member> selectAll(Connection conn) throws Exception {
		
		// 결과 저장용 변수
		List<Member> memberList = new ArrayList<Member>();
		
		try {
			
			// 1) SQL 작성
			String sql = prop.getProperty("selectAll");
			
			// 2) Statement 객체 생성
			stmt = conn.createStatement();
			
			// 3) SQL(SELECT) 수행 후 결과(ResultSet) 반환받기(rs 변수 사용)
			rs = stmt.executeQuery(sql);
			
			// 4)  ResultSet을 한 행씩 접근하여 조회된 컬럼값 을 얻어 와
			//	   Member 객체에 저장 (while문 사용하여 반복 접근)
			
			while(rs.next()) {
				
				String memberId = rs.getString("MEMBER_ID");
				String memberName = rs.getString("MEMBER_NM");
				Date enrollDate = rs.getDate("ENROLL_DATE");
				
				Member member = new Member();
				
				member.setMemberId(memberId);
				member.setMemberName(memberName);
				member.setEnrollDate(enrollDate);
				
				// 컬럼 값이 저장된 Member 객체를 List에 추가
				memberList.add(member);
				
			}
			
		} finally {
			
			// 6) 사용한 JDBC 자원 반환 (Connection 제외)
			close(rs);
			close(stmt);
			
		}
		
		// 7) 결과 반환
		return memberList;
	}


	/** 내 정보 수정 DAO
	 * @param conn
	 * @param updateMember
	 * @return result
	 * @throws Exception
	 */
	public int updateMyInfo(Connection conn, Member updateMember) throws Exception {
		
		int result = 0; // 결과 저장용 변수
		
		try {
			
			// 1) SQL 작성
			String sql = prop.getProperty("updateMyInfo");
			
			// 2) PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			
			// 3) 위치홀더 '?'에 알맞은 값 세팅
			pstmt.setString(1, updateMember.getMemberName());
			pstmt.setString(2, updateMember.getMemberGender()+"");
			pstmt.setInt(3, updateMember.getMemberNo());
			
			// 4) SQL(UPDATE) 수행 후 결과 (성공한 행의 개수 반환)
			result = pstmt.executeUpdate();
			
			
		} finally {
			
			// 5) 사용한 JDBC 자원 반환
			close(pstmt);
			
		}
		
		// 6) 결과 반환
		return result;
	}


	 /** 비밀번호 변경 DAO
	    * @param conn
	    * @param memberNo
	    * @param currentPw
	    * @param newPw
	    * @return result
	    * @throws Exception
	    */
	   public int updatePw(Connection conn, int memberNo, String currentPw, String newPw) throws Exception{

	      int result = 0; // 결과 저장할 변수 선언
	      
	      try {
	         // 1) SQL
	         String sql = prop.getProperty("updatePw");
	         
	         // 2) PreparedStatement 생성
	         pstmt = conn.prepareStatement(sql);
	         
	         // 3) 위치 홀더에 알맞은 값 대입
	         pstmt.setString(1, newPw);
	         pstmt.setInt(2, memberNo);
	         pstmt.setString(3, currentPw);
	         
	         // 4) SQL(UPDATE) 수행 후 결과(성공한 행의 개수) 반환
	         result = pstmt.executeUpdate();
	         
//	         System.out.println("test");
	         
	      }finally {
	         // 5) 사용한 JDBC 객체 자원 반환
	         close(pstmt);
	      }
	      // 6) 결과 반환
	      return result;
	   }


	/** 회원 탈퇴 DAO
	 * @param conn
	 * @param memberNo
	 * @param memberPw
	 * @return result
	 * @throws Exception
	 */
	public int secession(Connection conn, int memberNo, String memberPw) throws Exception {
		
		int result = 0;
		
		try {
			String sql = prop.getProperty("secession");
			
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setInt(1, memberNo);
			pstmt.setString(2, memberPw);
			
			result = pstmt.executeUpdate();
			
		} finally {
			close(pstmt);
		}
		
		
		return result;
	}


}

Member

package edu.kh.jdbc.member.model.vo;

import java.sql.Date;

// VO(Value Object): 값을 저장하는 용도의 객체
// -> 여러 값을 하나의 객체에 저장하여 매개변수 전달, 반환, 컬렉션 등에 이용할 수 있다.

public class Member {
	
	// 필드
	private int memberNo;
	private String memberId;
	private String memberPw;
	private String memberName;
	private char memberGender; // DB에는 char 타입이 없지만 Java에서 따로 변환해줄 거임
	private Date enrollDate;
	private char secessionFlag;
	
	// 기본 생성자(필수)
	public Member(){}

	// 회원 가입용 생성자(선택)
	public Member(String memberId, String memberPw, String memberName, char memberGender) {
		super();
		this.memberId = memberId;
		this.memberPw = memberPw;
		this.memberName = memberName;
		this.memberGender = memberGender;
	}

	// getter / setter (필수)
	public int getMemberNo() {
		return memberNo;
	}

	public void setMemberNo(int memberNo) {
		this.memberNo = memberNo;
	}

	public String getMemberId() {
		return memberId;
	}

	public void setMemberId(String memberId) {
		this.memberId = memberId;
	}

	public String getMemberPw() {
		return memberPw;
	}

	public void setMemberPw(String memberPw) {
		this.memberPw = memberPw;
	}

	public String getMemberName() {
		return memberName;
	}

	public void setMemberName(String memberName) {
		this.memberName = memberName;
	}

	public char getMemberGender() {
		return memberGender;
	}

	public void setMemberGender(char memberGender) {
		this.memberGender = memberGender;
	}

	public Date getEnrollDate() {
		return enrollDate;
	}

	public void setEnrollDate(Date enrollDate) {
		this.enrollDate = enrollDate;
	}

	public char getSecessionFlag() {
		return secessionFlag;
	}

	public void setSecessionFlag(char secessionFlag) {
		this.secessionFlag = secessionFlag;
	}

	// toString() 오버라이딩 (선택)
	@Override
	public String toString() {
		return "Member [memberNo=" + memberNo + ", memberId=" + memberId + ", memberPw=" + memberPw + ", memberName="
				+ memberName + ", memberGender=" + memberGender + ", enrollDate=" + enrollDate + ", secessionFlag="
				+ secessionFlag + "]";
	}
	

}

CreateXML

package edu.kh.jdbc.common;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class CreateXML { // 혼자서 실행하면 파일 사라집니다. 주의!!!!
	
	// XML(eXtensible Markup Language): 단순화된 데이터 기술 형식
	
	// XML 사용하려는 이유
	// - DB 연결, SQL같이 수정이 빈번한 내용을
	//   코드에 직접 작성하면 좋지 않다.
	
	//--> Java == 컴파일 언어 -> 코드가 조금만 수정되어도 전체 컴파일 다시 함
	//						--> 시간이 오래 걸림
	
	// 그런데, XML 외부 파일을 이용해서 XML 내용을 바꿔도
	// Java에서 XML 파일을 읽어오는 코드는 변하지 않음 --> 컴파일 X --> 시간 효율 상승
	
	public static void main(String[] args) {
		
		// XML은 K : V 형식의 map, XML은 문자열만 저장
		
		// Map<String, String> == Properties
		
		// * Properties 컬렉션 객체 *
		// 1. <String, String> 으로 Key, Value가 타입 제한된 Map
		// 2. XML 파일을 생성하고 읽어오는 데 특화
		
		Properties prop = new Properties();
		
		try {
			
			
			FileOutputStream fos = new FileOutputStream("member-sql.xml");
														// 파일 이름
									// 주석
			prop.storeToXML(fos, "Member Service SQL"); // XML 파일 생성
			// surround try catch
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	

}

member-sql.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>Member Service SQL</comment>
	
	<!-- 회원 가입 -->
	<entry key="signUp">
		INSERT INTO MEMBER
		VALUES(SEQ_MEMBER_NO.NEXTVAL, ?, ?, ?, ?, DEFAULT, DEFAULT)
	</entry>
	
	<!-- 로그인 -->
	<entry key="login">
		SELECT MEMBER_NO, MEMBER_ID, MEMBER_NM, MEMBER_GENDER, ENROLL_DATE FROM MEMBER 
		WHERE MEMBER_ID = ?
		AND MEMBER_PW = ?
		AND SECESSION_FL = 'N'
	</entry>
	
	<!-- 가입된 회원 목록 조회 -->
	<entry key="selectAll">
		SELECT MEMBER_ID, MEMBER_NM, ENROLL_DATE
		FROM MEMBER
		WHERE SECESSION_FL = 'N'
		ORDER BY MEMBER_ID
	</entry>
	
	<!-- 내 정보 수정 -->
	<entry key="updateMyInfo">
		UPDATE MEMBER
		SET MEMBER_NM = ?, MEMBER_GENDER = ?
		WHERE MEMBER_NO = ?
	</entry>
	
	<!-- 비밀번호 변경 -->
	<entry key="updatePw">
		UPDATE MEMBER
		SET MEMBER_PW = ?
		WHERE MEMBER_NO =?
		AND MEMBER_PW =?
	</entry>
	
	<!-- 회원 탈퇴 -->
	<entry key = "secession">
		UPDATE MEMBER
		SET SECESSION_FL = 'Y'
		WHERE MEMBER_NO =?
		AND MEMBER_PW =?
	</entry>
</properties>
profile
개발 일지

0개의 댓글