열심히 끝까지

디바이스 융합 자바(Java) day22 - 외래키,깃허브,비즈니스메서드(핵심관심,횡단관심(공통로직)),JDBC이용한 홈페이지 제작 본문

디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)

디바이스 융합 자바(Java) day22 - 외래키,깃허브,비즈니스메서드(핵심관심,횡단관심(공통로직)),JDBC이용한 홈페이지 제작

노유림 2022. 7. 12. 16:49

>> 속해 있는 곳

 

CREATE
DROP 
-- DDL

INSERT
SELECT
UPDATE
DELETE
-- DML

 

외래키
    -> SQL 

CREATE TABLE TEST1(
   NUM INT PRIMARY KEY,
   NAME VARCHAR(20) NOT NULL
);
-- 카테고리 EX ) 소주, 맥주, 와인, ... / 빵, 야채, 치즈, ...
INSERT INTO TEST1 VALUES(101, '신발');
INSERT INTO TEST1 VALUES(102, '가방');
INSERT INTO TEST1 VALUES(103, '음료');
INSERT INTO TEST1 VALUES(104, '밀키드');
SELECT * FROM TEST1;

CREATE TABLE TEST2(
   PNUM INT PRIMARY KEY,
   PNAME VARCHAR(20) NOT NULL,
   NUM INT -- FK(라고 주석)
   -- 다른 테이블의 PK 정보를 자신 테이블에서 일반 컬럼으로 이용하는 경우
          
   -- 여기(VARCHAR)에 그냥 카테고리를 넣으면 되지 않나?
   -- 신발을 구두, 운동화, 슬리퍼 로 구분할 건데 다 따로 구분해야 한다
);
-- 다른 테이블의 PK 정보를 자신 테이블에서 일반 컬럼으로 이용하는 경우
   -- >> 외래키(타 테이블의 PK 여야한다)(FK, FOREIGN KEY)
   -- FOREIGN 키를 걸 수 있지만 걸게 되면 강제성이 생긴다.
     -- >> 개발자에게는 좋음 -> 그래서 불편함(테이블 변경이 잘 안됨)
        
INSERT INTO TEST2 VALUES(11,'운동화',101);
SELECT * FROM TEST2;

 

>> 작은 홈페이지 작성

-- MVC 다 할 것

CREATE TABLE 회원 + 게시글
             회원 + 상품 << 시도할 것
             게시글 + 댓글 + 회원 + 대댓글
             
CREATE TABLE MEMBER(
    MID VARCHAR(20) PRIMARY KEY,
    MPW VARCHAR(20) NOT NULL,
    MNAME VARCHAR(20) NOT NULL
);

INSERT INTO MEMBER VALUES('ADMIN','1234','관리자'); -- 관리자 ID, PASSWORD,NAME
SELECT * FROM MEMBER;

CREATE TABLE PRODUCT(
    PID INT PRIMARY KEY,
    PNAME VARCHAR(20) NOT NULL,
    CNT INT,
    PRICE INT
);
INSERT INTO PRODUCT VALUES(101,'운동화',2,29000);
INSERT INTO PRODUCT VALUES(102,'장편소설',10,35000);
SELECT * FROM PRODUCT;

----ProductVO

package model;

public class ProductVO {
	private int pid;
	private String pname;
	private int price;
	private int cnt;
	
	public int getPid() {
		return pid;
	}
	public void setPid(int pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public int getCnt() {
		return cnt;
	}
	public void setCnt(int cnt) {
		this.cnt = cnt;
	}
	@Override
	public String toString() {
		return "ProductVO [pid=" + pid + ", pname=" + pname + ", price=" + price + ", cnt=" + cnt + "]";
	}
	
}

----ProductDAO

package model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

public class ProductDAO {
	Connection conn;
	PreparedStatement pstmt;
	// CRUD
	// 제품 추가
	// R
	// 제품 목록보기(SelectAll)(서비스)
	// 제품 상세보기(서비스)
	// 검색하기(SelectAll)(서비스)
	// U
	// 재고추가
	// 가격 변경
	// 구매(서비스)
	// D
	// 제품 삭제
	final String sql_selectAll="SELECT * FROM PRUDUCT";
	final String sql_selectOne = "SELECT * FROM PRODUCT WHERE PID=?";
	final String sql_update = "UPDATE PRDUCT SET CNT = CNT-1 WHERE PID=?";
	public ArrayList<ProductVO> selectAll(ProductVO vo) {
		ArrayList<ProductVO> datas = new ArrayList<ProductVO>();
		conn = JDBCUtil.connect();
		try {
			pstmt = conn.prepareStatement(sql_selectAll);
			ResultSet rs = pstmt.executeQuery();
			while(rs.next()) {
				ProductVO data = new ProductVO();
				data.setCnt(rs.getInt("cnt"));
				data.setPid(rs.getInt("pid"));
				data.setPname(rs.getString("pname"));
				data.setPrice(rs.getInt("price"));
				datas.add(data);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			JDBCUtil.disconnect(pstmt, conn);
		}
		return datas;
	}
	
	public ProductVO selectOne(ProductVO vo) { 
		conn = JDBCUtil.connect();
		try {
			pstmt = conn.prepareStatement(sql_selectOne);
			pstmt.setInt(1, vo.getPid());
			ResultSet rs = pstmt.executeQuery();
			if(rs.next()) {
				ProductVO data = new ProductVO();
				data.setCnt(rs.getInt("cnt"));
				data.setPid(rs.getInt("pid"));
				data.setPname(rs.getString("pname"));
				data.setPrice(rs.getInt("price"));
				return data;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally {
			JDBCUtil.disconnect(pstmt, conn);
		}
		return null;
	}
	public boolean update(ProductVO vo) { 
		// 1. 빼기 전에 재고 < 요청하는 양 실패
		// 2. 빼고 나서 재고 < 0 확인 -> 되돌리기 [트랜잭션] mysql공부할 때 배움(이번주 목,금)
		conn = JDBCUtil.connect();
		try {
			pstmt = conn.prepareStatement(sql_update);
			pstmt.setInt(1, vo.getPid());
			int res = pstmt.executeUpdate();
			if(res<=0) {
				System.out.println("로그 : 구매 실패...");
				return false;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		finally {
			JDBCUtil.disconnect(pstmt, conn);
		}
		return true;
	}
	// 3번이 여기서 진행되는 핵심 관심(concern) 18~26
	// 1,2,4번이 진행되는 횡단 관심 ㅡ 드라이브 로드, 연결, 
	//    >> 모듈화 가능
}

 

----MemberVO

package model;

public class MemberVO {
	private String mid;
	private String mpw;
	private String mname;
	public String getMid() {
		return mid;
	}
	public void setMid(String mid) {
		this.mid = mid;
	}
	public String getMpw() {
		return mpw;
	}
	public void setMpw(String mpw) {
		this.mpw = mpw;
	}
	public String getMname() {
		return mname;
	}
	public void setMname(String mname) {
		this.mname = mname;
	}
	@Override
	public String toString() {
		return "MemberVO [mid=" + mid + ", mpw=" + mpw + ", mname=" + mname + "]";
	}
	
}

 

----MemberDAO

package model;

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

public class MemberDAO {
	Connection conn;
	PreparedStatement pstmt;
	// CRUD
	// 회원가입
	// R
	// 로그인
	// 로그아웃
	// 마이페이지(에서 내 정보 확인)
	// 회원정보 변경(U)
	// 회원 탈퇴
	final String sql_login="SELECT * FROM MEMBER WHERE MID=?"; // 대문자로
	// 둘 중에서 어떤거로 실행이 불가한지 모르기 때문에 비번과 아이디 따로 로그 띄우기
	public MemberVO login(MemberVO vo) { // 이례적으로 
		conn = JDBCUtil.connect();
		try {
			pstmt = conn.prepareStatement(sql_login);
			pstmt.setString(1,vo.getMid());
			ResultSet rs = pstmt.executeQuery();
			if(rs.next()) { // 결과값의 mpw와 vo.getMpw()가 같니?
				if(rs.getString("mpw").equals(vo.getMpw())) {
					MemberVO data = new MemberVO();
					data.setMid(rs.getString("mid")); // 대문자 MID가 된다...
					data.setMname(rs.getString("mname"));
					data.setMpw(rs.getString("mpw"));
					System.out.println("로그 : 로그인 성공");
					return data;
				}
				System.out.println("로그 : 비밀번호 불일치로 로그인 실패");
				return null;
			}
			System.out.println("로그 : 회원정보 없음 | 로그인 실패...");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally {
			JDBCUtil.disconnect(pstmt, conn);
		}
		// 1. DB에 해당 아이디가 있나?
		// 2. DB에서 찾은 그 정보에 맞는 비밀번호인가?
		return null;
	}
	
}

 

----View

package view;

import java.util.ArrayList;
import java.util.Scanner;

import model.MemberVO;
import model.ProductVO;

public class View {
	Scanner sc = new Scanner(System.in);
	public MemberVO loginPage() { // 로그인 페이지
		System.out.print("아이디 입력 : ");
		String mid = sc.nextLine();
		System.out.print("비밀번호 입력 : ");
		String mpw = sc.nextLine();
		
		MemberVO vo = new MemberVO();
		vo.setMid(mid);
		vo.setMpw(mpw);
		return vo;
	}
	public int mainPage(ArrayList<ProductVO> datas) { // 메인페이지
		System.out.println("상품목록");
		for(ProductVO v : datas) {
			System.out.println(v);
		}
		System.out.print("상품번호 입력 : ");
		int pid = sc.nextInt();
		return pid;
	}
	public String deepPage(ProductVO data) { // [상세페이지]
		System.out.println("상품명 : "+data.getPname());
		System.out.println("상품가격 : "+data.getPrice());
		System.out.println("상품재고 : "+data.getCnt());
		System.out.print("구매하시겠습니까?(Y/N) : ");
		String ans = sc.nextLine();
		return ans;
	}
}

 

----Controller

package controller;

import model.MemberDAO;
import model.MemberVO;
import model.ProductDAO;
import model.ProductVO;
import view.View;

public class Controller {
	ProductDAO pDAO;
	MemberDAO mDAO;
	View view;
	public Controller() {
		pDAO = new ProductDAO();
		mDAO = new MemberDAO();
		view = new View();
	}
	public void startApp() {
		while(true){	
			MemberVO mVO = view.loginPage();
			MemberVO data = mDAO.login(mVO);
			if(data==null) {
				// view.로그인 실패
				continue;
			}
			
			ProductVO pVO = new ProductVO();
			int pid = view.mainPage(pDAO.selectAll(pVO));
			pVO.setPid(pid);
			ProductVO pData = pDAO.selectOne(pVO);
			if(pData==null) {
				continue;
			}
			String res = view.deepPage(pData);
			if(res.equals("Y")) {
				
				// 구매할 때만 온전히 -1
				pDAO.update(pVO);
				System.out.println("C 로그 : 구매 O");
				continue;
			}
			System.out.println("C 로그 : 구매 X");
		}
	}

}

 

----Client

package client;

import controller.Controller;

public class Client {
	public static void main(String[] args) {
		Controller app = new Controller();
		
		app.startApp();
	}
}

 

----JDBCUtil

package model;

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

public class JDBCUtil {

	static final String driverName = "oracle.jdbc.driver.OracleDriver";
	static final String url = "jdbc:oracle:thin:@localhost:1521:xe";
	static final String user = "ryo";
	static final String passwd = "1234";

	// conn 객체 반환
	public static Connection connect() { // Connection 확보 로직
		Connection conn = null;
		try {
			Class.forName(driverName);

			conn = DriverManager.getConnection(url, user, passwd);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}
	// conn 객체 받아서 연결해제
	public static void disconnect(PreparedStatement pstmt, Connection conn) {
		try {
			pstmt.close();
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 



깃허브 
    -> MVC
    -> 코드공유 > 깃허브(지금도 발전)
    -> 블로그 만큼 중요(나중에 설명)

3개월 차에 1주일 정도 수업을 진행하는 것
>> 비즈니스 메서드
- 핵심관심(사용자들이 이용하는 주 기능) 
   >> 주 기능을 하기 위해 매번 반복적으로 들어가는 로직
        : 유효성 검사
        : 보안처리
        : 인증, 인가, 허가
        : 로그(로깅 처리)
        : ......
      >> 핵심관심을 처리하기 위해 앞이나 뒤에 반복적으로 들어가야 하는 로직
             : 횡단관심 또는 공통로직
       
- CRUD


피드백
>> 재고 데이터로 ArrayList 컬렉션
>> 관리자모드
>> 유효성 검사 UI/UX
>> MVC

다음 프로젝트(진도를 보고 결정, 7월 22일정도로 생각)
>> 과제 주제 정해주심...
 재고데이터 -> DB + JDBC
 MVC
 관리자모드 안만듦(DB에 처리)
 웹 크롤링 -> 샘플데이터
 >> 크롤링할 대상 잘 잡고 분석
 (타켓 브라우저 웹/앱 어플리케이션 분석과제)
 + DAO를 두 개 이상 쓸 것!