JDBC 적용

유요한·2022년 4월 21일
0

JDBC & MVC

목록 보기
4/4

MVC에 JDBC 적용

테이블 생성

● 먼저, MySQL에서 테이블을 만들어줘야 한다.
	create table user(
	useridx int primary key auto_increment,
	userid varchar(300) unique,
    # userpw는 중복이 가능하므로 unique를 넣으면 안된다.
    userpw varchar(300) not null,
    username varchar(300) not null,
    userage int,
    userphone varchar(300),
    useraddr varchar(1000)
);

create table product (
	prodnum int primary key auto_increment,
	prodname varchar(1000),
	prodprice int,
	prodamount int,
	prodinfo varchar(4000),
    # default 0 : 아무 값을 넣지 않으면 0이됨
	likecnt int default 0
);

Java 작성

build path 해주기

1. view - Index 클래스 생성

● 가장 먼저 나오는 페이지
	package view;

import java.util.Scanner;

//index : 시작하는 페이지
public class Index {
	public static void main(String[] args) {
		System.out.println("22.03 개강반 최종 프로젝트 / UMS 프로그램 입니다.");
		
		Scanner sc = new Scanner(System.in);
		while(true) {
			System.out.println("1. 회원가입\n2. 로그인\n3. 나가기");
			int choice = sc.nextInt();
			
			//Controller
			if(choice == 3) {
				System.out.println("안녕히가세요");
				break;
			}
			switch(choice) {
			case 1:
				// 회원가입
                // JoinView에서 생성자를 생성하고 코드를 작성한것을 메소드처럼 불러옴
                // 많은 데이터들의 입출력이 일어나기 때문에 코드가 길어진다.
				// 따라서 새로운 View를 띄워준다.(흐름을 이동시킨다)
				new JoinView();
				break;
			case 2:
				//로그인
				new LoginView();
				break;
			default:
				System.out.println("다시 입력하세요");
			}
		}
	}
}

2. view - JoinView 클래스 생성

● Index에 있는 회원가입을 나타내는 코드
● new JoinView();를 불러오기 위한 생성자 생성
   
	view / JoinView
package view;

import java.util.Scanner;

import dao.UserDAO;
import dto.UserDTO;
// 회원가입을 위해 생성
public class JoinView {
	// 생성자도 메소드랑 같은 역할을 한다.
	// 호출하면 내부로 와서 내부에 있는 내용 실행이 된다.
	// JoinView 생성자에 코드를 작성하고 Index에서 메소드처럼 불러오기
	public JoinView() {
		Scanner sc = new Scanner(System.in);
        //새로 가입할 "회원의 정보들" 을 데이터베이스에 저장해야 하므로
		//기능을 구현해 놓은 DAO가 필요하고, 회원 관련된 데이터이므로
		//UserDAO를 사용해야 한다.
		UserDAO udao = new UserDAO();
		
		System.out.print("아이디 : ");
		String userid = sc.next();
        // userid를 생성할때 중복검사 할 도구가 필요하다. 
        // 데이터와 통신할 클래스를 별도로 만드는데 DAO로 관리하면 된다.
        // DAO에는 데이터베이스와 직접 통신할 DBConnection Class와 직접 소통하는 클래스로 나눌 것이다. 
        // UserDAO에서 만든 메소드를 이용해 사용자 중복 검사를 실시하자
		if(udao.checkDup(userid)) {
			System.out.print("비밀번호 : ");
			String userpw = sc.next();
			System.out.print("이름 : ");
			String username = sc.next();
			System.out.print("나이 : ");
			int userage = sc.nextInt();
			System.out.print("핸드폰 번호 : ");
			String userphone = sc.next();
			System.out.print("주소 : ");
            // 새롭게 스캐너 객체를 만든이유는 nextLine()을 제대로 사용하기 위해서
			sc = new Scanner(System.in);
			String useraddr = sc.nextLine();
			
            //여기까지 왔다면 회원 가입에 필요한 모든 정보를 입력받았다는
			//뜻이므로, UserTable에 이 모든 데이터들을 저장해 주어야 한다.
			//저장하는 기능적인 코드들은 View에서 구현하는 것이 아니고
			//Userdao에 구현해 놓고 메소드를 호출하는 식으로 사용한다.
			//호출시 넘겨주어야 할 데이터들이 총 6개나 되므로 UserDTO 타입의
			//객체 하나로 포장해서 그 객체를 매개변수에 넘겨준다.
			UserDTO user = new UserDTO(userid, userpw, username, userage, userphone, useraddr);
            // UserDAO에서는 여기서 입력한 것들을 보내주기 위해서 포장한 DTO 객체를 매개변수로 넘겨준다.
            // user을 UserDAO에 넘겨준다.
			if(udao.join(user)) {
				System.out.println("회원가입 성공!");
				System.out.println(username+"님 가입을 환영합니다!");
			}
			else {
				System.out.println("회원가입 실패 / 다시 시도해 주세요.");
			}
		}
		else {
			System.out.println("중복된 아이디가 있습니다. 다시 시도해 주세요.");
		}
	}
}

3. DBConnection

● 모든 클래스에 만들 필요 없이 여기에 한번에 만들고 불러오는 형식으로 사용
	package dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class DBConnection {
	private static Connection conn;
	
	public static Connection getConnection() {
		// 싱글톤 패턴 : 단 하나의 객체만 만들어서 사용하도록 설계된 패턴
		if(conn == null) {
			try {
				Class.forName("com.mysql.cj.jdbc.Driver");
				System.out.println("드라이버 로딩 성공!");
				
				// 다리를 짓고자 하는 목적지
				String url = "jdbc:mysql://localhost:3306/web0315";
				String user = "root";
				String password = "1234";
				
				conn = DriverManager.getConnection(url, user, password);
				
				
				
			} catch (ClassNotFoundException cnfe) {
				System.out.println("드라이버 로딩 실패 : " + cnfe);
			} catch(SQLException sqle) {
				System.out.println("DB 연결 실패 : " + sqle);
			}
		}
		return conn;
	
	}
}

4. dao - UserDAO 클래스 생성

● JoinView를 구성하기 위한 UserDAO

▼ view - JoinView 클래스에서 아래서 나와 있는 if(udao.checkDup(userid)) { 중복검사를 돌려주는 코드

	if(udao.checkDup(userid)) {
			System.out.print("비밀번호 : ");
			String userpw = sc.next();
			System.out.print("이름 : ");
			String username = sc.next();
			System.out.print("나이 : ");
			int userage = sc.nextInt();
			System.out.print("핸드폰 번호 : ");
			String userphone = sc.next();
			System.out.print("주소 : ");
			sc = new Scanner(System.in);
			String useraddr = sc.nextLine();
● UserDAO 내부 → 중복검사(checkDup)
	// 중복 검사는 'read' 그래서 SQL문에서는 'select'를 사용한다.
	// 우리가 받아올 userid를 맨 끝에 세팅을 할 거니까 '?'로 써준다.
	// 있으면 중복, 아니면 중복 아님
	public boolean checkDup(String userid) {
		String sql = "select * from user where userid=?";
		try {
			// 만들어논 다리를 이용(만들어 놓은 다리 위를 왔다갔다 할 택배차 만들기)
			// prepareStatement 메소드에 우리가 시행하고자 할 sql문을 넘겨주면서 뽑아준다.
			ps = conn.prepareStatement(sql);
           ps.setString(1, userid);
           
			// executeUpdate()	: 
           // 시스템에 변화가 생기는 쿼리문 수행(insert, update, delete)-변화된 행의 개수 리턴
			// executeQuery()	: 변화 없는 쿼리문 수행(select)-검색된 결과 리턴(ResultSet)
			// 여기서는 select를 사용하니까 executeQuery()를 사용
			// 가지고오는 결과가 ResultSet rs인데 테이블 자체를 받아온다.
           // 테이블은 데이터가 아니기 때문에 rs.next를 사용해서 데이터를
           // 가져오는 형식
			rs = ps.executeQuery();
			
			// 그냥 return하면 중복되는게 있으면 true니까 !rs.next();을 해야 한다.
			// 그래야 중복된게 없어야 true가 나오니까
			return !rs.next();
		} catch (SQLException sqle) {
			System.out.println("쿼리 수행 실패! : " + sqle);
		}
		return false;
	}
● UserDAO 내부 → 회원가입(join)
	public boolean join(UserDTO user) {
		// values(?,?,?,?,?,?)에서 ?는  (userid,userpw,username,userage,userphone,useraddr)
		// 값들이다.
		String sql = "insert into user (userid,userpw,username,userage,userphone,useraddr) "
				+ "values(?,?,?,?,?,?)";
		
		try {
       // JoinView에서 매개변수로 받을 값들을 사용
			ps = conn.prepareStatement(sql);
			ps.setString(1, user.userid);
			ps.setString(2, user.userpw);
			ps.setString(3, user.username);
			ps.setInt(4, user.userage);
			ps.setString(5, user.userphone);
			ps.setString(6, user.useraddr);
			
			
			// 여기서는 insert니까 executeUpdate()
			// executeUpdate()는 ResultSet rs 사용 안해도 된다.
			// 1개가 있으면 true
			return ps.executeUpdate() == 1;
			
		} catch (SQLException sqle) {
			System.out.println("쿼리 수행 실패! : " + sqle);
		}
		return false;
	}

5. dao - Session 클래스 생성

	package dao;

	import java.util.HashMap;

public class Session {
	//Session.datas.put("login_id","apple");
	private static HashMap<String, String> datas = new HashMap<String, String>();

	
	//Session.put("login_id","apple");
	public static void put(String key, String value) {
		datas.put(key, value);
	}
	public static String get(String key) {
		return datas.get(key);
	}
}

6. view - LoginView 클래스 생성

●  Index 클래스에 있는 new LoginView(); 작성
	package view;

import java.util.Scanner;

import dao.UserDAO;

public class LoginView {
	public LoginView() {
		Scanner sc = new Scanner(System.in);
		UserDAO udao = new UserDAO();
		
		System.out.print("아이디 : ");
		String userid = sc.next();
		System.out.print("비밀번호 : ");
		String userpw = sc.next();
		
		if(udao.login(userid,userpw)) {
			System.out.println(userid+"님 어서오세요~");
			
			//메인창 띄우기
			new MainView();
		}
		else {
			System.out.println("로그인 실패 / 다시 시도해 주세요.");
		}
	}
}

7. UserDAO 내부에 있는 login 메소드 작성

● LoginView에 있는 if(udao.login(userid,userpw)) {
  완성하기 위해서
		//							apple		 abcd1234
	public boolean login(String userid, String userpw) {
		String sql = "select * from user where userid =? and userpw=?";
		
		try {
			ps =conn.prepareStatement(sql);
			ps.setString(1, userid);
			ps.setString(2, userpw);
			
			rs = ps.executeQuery();

			if(rs.next()) {
				Session.put("login_id", userid);
				// 검색은 pk(primary key)가 가장 빠름
				// 그래서 pk인 useridx를 Session에 세팅하고 싶으면 아래와 같은 방법사용
				// 정수니까 +""해서 문자열로 바꾸기
				Session.put("login_idx", rs.getInt("useridx") + "");
                return true;
			}
		} catch (SQLException sqle) {
			System.out.println("쿼리 수행 실패! : " + sqle);
		}
		return false;
	}

8. view - MainView 클래스 생성

	package view;

import java.util.Scanner;

import dao.ProductDAO;
import dao.ProductDAO;
import dao.Session;

public class MainView {
	public MainView() {
		Scanner sc = new Scanner(System.in);
		ProductDAO pdao = new ProductDAO();
		
		while(true) {
			//우리가 만든 프로젝트는 무조건 main()부터 시작하는 프로그램이다.
			//즉 진입점이 한개이기 때문에 아래와 같은 코드를 생략 가능하다.
			//*웹 상이나 다른 프로그램에서는 진입점이 여러개일 수 있으므로
			//아래처럼 로그인 되어있는지를 먼저 검사해주는것이 필요하다.
			if(Session.get("login_id") == null) {
				System.out.println("로그인 후 이용하세요");
				break;
			}
			System.out.println("☆★☆★☆★☆★"+Session.get("login_id")+"님 어서오세요~☆★☆★☆★☆★\n"
					+ "1. 상품추가\n2. 상품수정\n3. 상품삭제\n"
					+ "4. 내 상품 보기\n5. 상품 검색\n6. 내 정보 수정\n7. 로그아웃");
			int choice = sc.nextInt();
			
			if(choice == 7) {
				//로그아웃
				System.out.println(Session.get("login_id")+"님 안녕히가세요~");
				//로그인한 정보를 담아주는 Session에서 login_id라는 KEY 와 쌍을 이루고 있는 값은
				//로그아웃을 했다면 없애주어야 한다. 따라서 null로 초기화 해주어야 한다.
				Session.put("login_id", null);
				break;
			}
			switch(choice) {
			case 1:
				//상품추가
				new AddProductView();
				break;
			case 2:
				//상품수정
				new ModifyProductView();
				break;
			case 3:
				//상품삭제
				//내 상품 목록 띄워주고 번호 입력받아서 삭제시키기
				System.out.println(pdao.getList());
				System.out.print("삭제할 상품 번호 : ");
				int prodnum = sc.nextInt();
				if(pdao.removeProduct(prodnum)) {
					System.out.println(prodnum+"번 상품 삭제 성공!");
				}
				else {
					System.out.println("알 수 없는 오류 / 다음에 다시 시도해 주세요.");
				}
				break;
			case 4:
				//내 상품 보기
				System.out.println("===========내가 올린 상품 목록===========");
				System.out.println(pdao.getList());
				System.out.println("===================================");
				break;
			
			case 5:
				//내 정보 수정
				new MyInfoView();
				break;
			}
			
		}
	}
}

9. AddProductView 클래스 생성

● MainView에 있는 new AddProductView();을 만들기 위해 생성
● 상품 추가
	package view;

import java.util.Scanner;

import dao.ProductDAO;
import dao.Session;
import dto.ProductDTO;

public class AddProductView {
	public AddProductView() {
		//상품에 관련된 정보에 접근할 객체인 pdao 생성(상품 관련된 기능들이 선언되어 있다.)
		ProductDAO pdao = new ProductDAO();
		Scanner sc = new Scanner(System.in);
		
		System.out.print("상품 이름 : ");
		String prodname = sc.nextLine();
		System.out.print("상품 가격 : ");
		int prodprice = sc.nextInt();
		System.out.print("상품 재고 : ");
		int prodamount = sc.nextInt();
		System.out.print("상품 소개 : ");
		sc = new Scanner(System.in);
		String prodinfo = sc.nextLine();
		
		//지금 추가중인 상품의 상품번호는 현재 "추가되어 있는 마지막 상품의 번호"+1로 설정해 주어야 한다.
		//pdao에 getLastNum()을 만들어서 리턴받고 +1 해준 것을 상품 번호로 사용한다.
		ProductDTO product = new ProductDTO(pdao.getLastNum()+1, prodname, prodprice,
				prodamount, prodinfo, Session.get("login_id"));//올린 사람은 현재
		//								로그인 되어 있는 유저이므로 세션에서 아이디를 받아온 후 사용
		
		//포장이 끝났다면 pdao의 메소드에 객체 넘겨주기
		if(pdao.addProduct(product)) {
			System.out.println(prodname+" 상품 추가 완료!");
		}
		else {
			System.out.println("알 수 없는 오류 / 다음에 다시 시도해 주세요.");
		}
	}
}

10. view - ModifyProductView 클래스 생성

● MainView 클래스에 있는 new ModifyProductView(); 만들기 위해서 생성
● 상품 수정
	package view;

import java.util.Scanner;

import dao.ProductDAO;

public class ModifyProductView {
	public ModifyProductView() {
		ProductDAO pdao = new ProductDAO();
		Scanner sc = new Scanner(System.in);
		//내가 올린 상품 목록 출력
		System.out.println(pdao.getList());
		System.out.print("수정할 상품 번호 : ");
		int prodnum = sc.nextInt();
		System.out.println("1. 가격수정\n2. 재고수정\n3. 설명수정");
		int choice = sc.nextInt();
		System.out.print("새로운 정보 : ");
		sc = new Scanner(System.in);
		String newData = sc.nextLine();
		
		//세가지 입력받은 데이터를 DAO에 넘겨주기(행, 열, 새로운 데이터)
		if(pdao.modifyProduct(prodnum,choice,newData)) {
			System.out.println(prodnum+"번 상품이 정상적으로 수정되었습니다.");
		}
		else {
			System.out.println("알 수 없는 오류 / 다음에 다시 시도해 주세요.");
		}
	}
}

11. dao - ProductDAO 클래스 생성

● ModifyProductView 클래스에 있는 modifyProduct 메소드를 완성하기 위해 생성
	public boolean modifyProduct(int prodnum, int choice, String newData) {
		String[] cols = {"prodprice", "modstock", "moddetail"};
		String sql = "update product set prodnum=?, " + cols[choice -1] + "=? where userid =?";
		
		
		try {
			ps = conn.prepareStatement(sql);
			ps.setInt(1, prodnum);
			ps.setString(2, newData);
			ps.setString(3, Session.get("login_id"));
			
			return ps.executeUpdate() == 1;
			
		} catch (SQLException sqle) {
			System.out.println("쿼리 수행 실패! : " + sqle);
		}
		return false;
	}

12. view - MyInfoView 클래스 생성

● MainView에 있는 new MyInfoView()를 완성하기 위해 만듬
	package view;

import java.util.Scanner;

import dao.ProductDAO;
import dao.UserDAO;

public class MyInfoView {
	public MyInfoView() {
		Scanner sc = new Scanner(System.in);
		UserDAO udao = new UserDAO();
		ProductDAO pdao = new ProductDAO();
		
		System.out.println(udao.myInfo());
		System.out.println("1. 비밀번호 수정\n2. 핸드폰 번호 수정\n3. 주소 수정\n4. 수정 취소\n5. 회원탈퇴");
		int choice = sc.nextInt();
		if(choice == 4) {
			System.out.println("메인으로 돌아갑니다.");
		} else if(choice == 5) {
			System.out.print("비밀번호 재입력 : ");
			String userpw = sc.next();
			//비밀번호 검사를 위해 udao의 checkPw() 호출
			if(udao.checkPw(userpw)) {
				//회원탈퇴 진행
				//탈퇴 진행 시 현재 탈퇴를 하려는 회원이 올린 모든 상품들도 삭제 혹은 사용불가 처리를 해주어야 한다.
				//후에 삽입될 데이터와 충돌이 발생할 수 있기 때문이다. 상품을 관리할 pdao를 통해 removeAll()을
				//먼저 진행해준다. *실제 DB 환경에서도 상품 삭제가 먼저 되어야지만 회원을 탈퇴 시킬 수 있다.
				pdao.removeAll();
				//상품까지 깨끗하게 처리되었으므로 실제 회원 데이터 삭제 진행
				if(udao.leaveId()) {
					//아련하게 인사
					System.out.println("그동안 이용해 주셔서 감사합니다...☆ 기다릴게요....");
				}
			}
			//비밀번호 검사 실패
			else {
				System.out.println("비밀번호 오류");
			}
		}
		//무언가 회원 정보를 수정하려고 선택했을 때
		else {
			System.out.print("새로운 정보 : ");
			sc = new Scanner(System.in);
			String newData = sc.nextLine();
			
			
			boolean check = false;
			// choice는 "1. 비밀번호 수정 2. 핸드폰 번호 수정 3. 주소 수정
			check = udao.modifyUser(choice, newData);
			
			if(check) {
				System.out.println("정보 수정 완료!");
			}
			else {
				System.out.println("정보 수정 실패");
			}
		}
	}
}

13. dao - UserDAO

● MyInfoView 클래스의 System.out.println(udao.myInfo());를
  사용하기 위해 만들어 준다.
● MyInfoView 클래스의 udao.modifyUser(choice, newData);를
  구현하기 위해 만들어 준다.
	public String myInfo() {
		String sql = "select * form user where userid =?";
		
		try {
			ps = conn.prepareStatement(sql);
			ps.setString(1, Session.get("login_id"));
			
			rs = ps.executeQuery();
			
			while(rs.next()) {
				String id = rs.getString("userid");
				String pw = rs.getString("userpw");
				String name = rs.getString("username");
				int age = rs.getInt("userage");
				String phonenum = rs.getString("userphone");
				String addr = rs.getString("useraddr");
				
				return "아이디 : " + id +"\n비번 : " + pw + "\n이름 : " + name + "\n나이 : " + age 
						+ "\n핸드폰 번호 : " + phonenum + "\n주소 : " + addr;
						
			}
			
		} catch (SQLException sqle) {
			System.out.println("쿼리 수행 실패! : " + sqle);
		}
		return null;
	}
	public boolean modifyUser(int col, String newData) {
		// col : 1. 비밀번호 수정 / 2.핸드폰 번호 수정 / 3. 주소수정
		// ▼ SQL문이 일정하지가 않음(상황에따라 컬럼명이 바뀜)
		// 1번 선택 : "update user set userpw= 'abcd1234' where userid ='apple'
		// 2번 선택 : "update user set userphone= '01012341234' where userid='apple'
		String[] cols ={"userpw","userphone","useraddr"};
		// cols[col -1] 이렇게 하면 매개변수로 오는 번호에 -1을 해준다. 
		// 예를들어 비밀번호 수정하려고 1번을 넣어주면 1 - 1 = 0이 되서 cols에 있는 배열 0번자리가
		// 와서 'userpw'를 사용한다.
		String sql = "update user set " + cols[col -1] + "=? where userid=?";
		
		try {
			ps = conn.prepareStatement(sql);
			ps.setString(1, newData);
			ps.setString(2, Session.get("login_id"));
			
			// 한개가 잘 수정이 됐다면 true
			return ps.executeUpdate() == 1;
			
		} catch (SQLException sqle) {
			System.out.println("쿼리 수행 실패! : " + sqle);
		}
		
		return false;
	}
profile
최선을 다하자!!

0개의 댓글