Member 게시판 만들기
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();
}
}
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);
}
}
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;
}
}
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;
}
}
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;
}
}
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 + "]";
}
}
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();
}
}
}
<?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>