2/19(금) JDBC

민국·2021년 2월 19일
0

JAVA - DB 연동

연동방식

JAVA 다시 보기

- MVC패턴

1) M : Model 데이터와 관련된 역할(데이터를 담거나, DB와 접근해서 데이터 입출력)

2) V : View 사용자가 보게 될 시각적인 요소/화면 (출력, 입력)

3) C : Controller 사용자의 요청을 받아서 처리 후 응답화면을 지정하는

1) Model

  • VO(Value Object)
    : 값을 담는 그릇과도 같음, DB테이블의 한 행에 대한 데이터를 기록할 수 있는 저장용 객체
    <유사용어>
    DTO : Data Transfer Object
    DO : Domain Object
    Entity : Strut에서는 이 용어 사용
    bean : EJB에서 사용
  • VO 조건
    (1) 반드시 캡슐화 적용
    (2) 기본 생성자 및 매개변수 생성자 작성할 것
    [Tip] alt+shift+s -> o(매개변수생성자), r(getter/setter), s(to String)

(3) 모든 필드에 대한 setter/getter 메소드 작성할 것

<데이터 전달 순서>
View => Controller => Dao => DB => Dao => Controller => View => Run(실행)

<JDBC 만들기 예시>
View = MemberMenu
Contoller = MemberController
Dao = MemberDao
DB = MEMBER

2) View

: 사용자가 보게 될 시각적인요소 (출력 및 사용자 입력)

<예시 : MemberMenu 클래스 내에 메소드 만들기>
< (1) 전체메뉴항목 만들기 -> (2) 메뉴 안에 1번 회원추가 만들기 >

package com.kh.view;

import java.util.Scanner;

import com.kh.controller.MemberController;

// View : 사용자가 보게 될 시각적인 요소(출력 및 입력)
public class MemberMenu {

	// 전역으로 다 쓸 수 있도록 Scanner 객체 생성
	private Scanner sc = new Scanner(System.in);
	
	// 전역으로 바로 MemberController 요청할 수 있게끔 객체생성
	private MemberController mc = new MemberController();
	
	/**
	 * 사용자가 보게 될 첫화면(메인화면)
	 */
	public void mainMenu() {
		
		while(true) {
			
			** syso + ctrl + space 축약키 => System.out.println 축약키 **
			System.out.println("\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("0. 프로그램 종료");
			System.out.println("이용할 메뉴 선택 : ");
			
			int menu = sc.nextInt();
			sc.nextLine();
			
			switch(menu) {
			case 1: insertMember(); break;
			case 2: selectMember(); break;
			case 3: break;
			case 4: break;
			case 5: break;
			case 6: break;
			case 0: System.out.println("이용해주셔서 감사합니다. 프로그램을 종료합니다."); return; 
			// break를 해버리면 switch 문만 빠져나가서 메뉴 다시 출력됨
			// return을 해버리면 mainMenu 메소드 자체를 빠져나가므로 Run클래스에서 
			// mainMenu 메소드를 빠져나가게 되면 이후 실행되는 메소드 없어서 끝남 
			
			default : System.out.println("\n메뉴 번호를 잘못 입력했습니다. 다시 입력해주세요.");
			
			}
		}
		
	}
	
	/**
	 * 1. 회원 추가용 화면
	 * 추가하고자 하는 회원의 정보를 입력받아서 추가 요청할 수 있는 화면
	 */
	public void insertMember() {
		System.out.println("\n==== 회원 추가 =====");
		
		System.out.print("아이디 : ");
		String userId = sc.nextLine();
		
		System.out.print("비밀번호: ");
		String userPwd = sc.nextLine();
		
		System.out.print("이름: ");
		String userName = sc.nextLine();
				
		System.out.print("성별(M/F): ");
		String gender = sc.nextLine().toUpperCase();
		
		System.out.print("나이: ");
		int age = sc.nextInt();
		sc.nextLine();
		
		System.out.print("이메일: ");
		String email = sc.nextLine();
		
		System.out.print("전화번호(-빼고): ");
		String phone = sc.nextLine();
		
		System.out.print("주소: ");
		String address = sc.nextLine();
		
		System.out.print("취미(,로 공백없이 나열): ");
		String hobby = sc.nextLine();
		
		// 회원 추가 요청! => Controller의 어떤 메소드 호출
		mc.insertMember(userId, userPwd, userName, gender, age, email, phone, address, hobby)
		
	}
	
	// ------------------------------------------
	
	// 서비스 요청 처리 후 사용자가 보게 될 응답화면들
	// 서비스 요청 성공 시 보게될 화면
	/**
	 * 서비스 요청 성공시 보게될 응답화면
	 * @param message 성공메세지
	 */
	public void displaySuccess(String message) {
		System.out.println("\n서비스 요청 성공 : " + message);		
	}
	
	/** alt + shift + j
	 * 서비스 요청 실패시 보게될 응답화면 
	 * @param message 실패메세지
	 */
	public void displayFail(String message) {
		System.out.println("\n서비스 요청 실패 : " + message);
	}
	
	
	
}

View 만들기 순서
1) 사용자가 값을 입력할 수 있도록 Scanner 객체, 또 Controller와 연결해주는 객체 생성
2) 서비스 요청 성공 시 사용자가 보게될 화면(성공치 보게될 화면, 실패시 보게 될 화면)
3) 사용자가 보게 될 메인 화면 구성(mainMenu 메소드 만들기)
3)-(1) 반복문 구성(메뉴화면)
3)-(2) 각 메뉴를 선택했을 경우 나타날 화면구성(1번 누르면 , 2번 누르면...)
3)-(3) 1번 메뉴 누르면 동작할 것들 controller - dao - db 연결시키기
: 회원추가 만들기 - insertMember메소드

3) Controller

:View를 통해서 요청한 기능 처리하는 담당
: 해당 메소드로 전달된 데이터 가공처리 한 후,
Dao 메소드로부터 반환받은 결과에 따라 사용자가 보게 될 View(응답화면)를 결정(View 메소드 호출)
<예시>
<예시 : MemberController 클래스 안에 각 기능별 메소드 만들기>
<(3) 회원추가에 담긴 값들 가공처리하기>
4) inserMember 메소드 3)-3에 담긴 값(변수)를 가공하기
4)-(1) Controller 클래스에 insertMember에 담긴 값을 담을 객체 생성하기!(값을 담을 박스 만들기)

package com.kh.controller;

// Controller 

public class MemberController {
	/**
     * 사용자의 회원 추가 요청을 처리해주는 메소드 
	 * @param userId, userPwd, userName, gender, age, email, phone, address, hobby
	 */
	public void insertMember(String userId, String userPwd, String userName, String gender, 
			                int age, String email, String phone, String address, String hobby) {
		
		
		// 전달된 데이터들을 Member객체 주섬주섬 담기
		Member m = new Member(userId, userPwd, userName, gender, age, email, phone, address, hobby);
	};
	
}
----------------------------------------------------------------------
<Member 객체>
// 회원추가용 생성자 추가해주기 
	public Member(String userId, String userPwd, String userName, String gender, int age, String email, String phone,
			String address, String hobby) {
		super();
		this.userId = userId;
		this.userPwd = userPwd;
		this.userName = userName;
		this.gender = gender;
		this.age = age;
		this.email = email;
		this.phone = phone;
		this.address = address;
		this.hobby = hobby;
---------------------------------------------------------------------

new MemberDao().insertMemeber(m);

새로운 객체를 만들었으므로 9가지의 매개변수를 담을 새로운 객체를 Member객체에 다시 설정 해주기(왜냐면 저 9가지를 담은 객체는 없으므로.. 그렇다고 매번 저 9개의 변수를 쓰기는 너무 비효율적이니까!)

자, 이제
2) 사용자가 입력한 View
=> 3) Controller 에서 전달된 데이터 가공처리(변수 만들기, 리스트 만들기 등...)
=> 4) Dao에서는 이제 DB와 연동시켜주는 내용의 메소드들 만들기!

4) DAO(Data Access Object)

: Controller를 통해서 호출된 기능을 수행하기 위해서 DB에 직접적으로 접근 한 후 해당 SQL문 실행 및 결과 받기 ( = JDBC )
아직, 하기 전에 JDBC용 객체가 뭐가 있는지 알아보자!

=> JDBC 설명듣고 이후에 다시 해보자!

5) JDBC용 객체

  • Connection : DB의 연결정보를 담고 있는 객체
  • [Prepared] Statement : 해당 DB에 SQL문을 전달하고 실행한 후 결과를 받아내는 객체
  • ResultSet : 만일 실행한 SQL문이 SELECT문일 경우 조회된 결과들이 담겨있는 객체

★ 6) JDBC 처리 순서

  • 1) jdbc driver 등록 : 해당 DBMS가 제공하는 클래스 등록
  • 2) Connection 생성 : 접속하고자 하는 DB정보를 입력해서 DB에 접속하면서 생성
  • 3) Statement 생성 : Connection 객체를 이용해서 생성
  • 4) sql문 전달하면서 실행 : Statement객체를 이용해서 sql문 실행
    • SELECT문일 경우 - executeQuery메소드를 이용해서 실행
    • DML문(update, insert, delete)일 경우 - executeUpdate메소드를 이용해서 실행
  • 5) 결과 받기
    • SELECT문일 경우 - ResultSet객체(조회된데이터들이담겨있음)로 받기 => 6-1)
    • DML문일 경우 - int(처리된 행수)로 받기 => 6-2)
  • 6_1) ResultSet에 담겨있는 모든 데이터들 하나씩 하나씩 뽑아서 vo객체에 주섬주섬 담기
  • 6_2) 트랜잭션 처리 (성공적이면 commit, 실패면 rollback)
  • 7) 다 쓴 JDBC용 객체들 반드시 자원반납 (close) => 생성된 역순으로
  • 8) 결과 반환 (Controller)
    • SELECT문일 경우 - 6-1) 만들어진 결과
    • DML문일 경우 - int(처리된행수)

4) Dao 작업

public int insertMember(Member m) { // insert문 => 처리된 행 수 => 트랜잭션 처리
		
		// 필요한 변수들 먼저 셋팅
		// 참고 -> 레퍼런스변수(어떤 지역에서 사용되는 변수)로 쓸 때는 먼저 변수를 초기화하는 습관을 들이자!
		int result = 0;			// 처리된 결과(처리된 행수)를 담아줄 변수
		Connection conn = null; // 접속된 DB의 연결정보를 담는 변수
		Statement stmt = null;	// sql문 실행 후 결과를 받기 위한 변수
		
		// 실행할 sql문(완성형태로 만들어둘것!!) => 끝에 세미콜론 있으면 안됨!!
		// INSERT INTO MEMBER VALUES(SEQ_USERNO.NEXTVAL, 'XXX', 'XXXX', 'XXX', 'X', XX, 'XXXX', 'XXXX', 'XXXX', 'XXXX', SYSDATE)
		String sql = "INSERT INTO MEMBER VALUES(SEQ_USERNO.NEXTVAL, "
				   						+ "'" + m.getUserId() 	+ "', "
				   						+ "'" + m.getUserPwd() 	+ "', "
				   						+ "'" + m.getUserName() + "', "
				   						+ "'" + m.getGender() 	+ "', "
				   							  + m.getAge()		+  ", "
				   						+ "'" + m.getEmail()	+ "', "
				   						+ "'" + m.getPhone()	+ "', "
				   						+ "'" + m.getAddress() 	+ "', "
				   						+ "'" + m.getHobby()	+ "', SYSDATE)";
		
		//System.out.println(sql);
		
		try {
			// 1) jdbc driver 등록
			Class.forName("oracle.jdbc.driver.OracleDriver"); // 
            		ClassNotFoundException 발생 
            		=> (1) ojdbc6.jar 누락됐다거나, 잘 추가됐지만 오타가 있을 경우
                           (2) library가 없을 경우 - ojdbc6.jar 누락 
			
			// 2) Connection 객체 생성 (DB와 연결 --> url, 계정명, 비밀번호)
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
			
			// 3) Statement 객체 생성
			stmt = conn.createStatement();
			
			// 4, 5) DB에 완성된 sql문 전달하면서 실행 후 결과(처리된행수) 받기
			result = stmt.executeUpdate(sql);
			
			// 6_2) 트랜잭션 처리 
			if(result > 0) { // 성공했을 경우
				conn.commit();
			}else { // 실패했을 경우 
				conn.rollback();
			}
			
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			
			try {
				// 7) 다쓴 JDBC용 객체 자원 반납 (생성된 역순으로)
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}
		
		// 8) 결과 반환
		return result; // 처리된 행 수
		// 하지만 빨간줄 뜸 -> 왜? 반환형을 아직 몰라서 메소드를 void로 만들어놨기 때문
        -> void => return 이 int 이므로 int 반환형으로 바꿔줌 
        => return 값은 이제 다시 Controller 클래스로 가게 됨 
	}

5) return 받는 Controller

Controller 메소드 뒤에 연결되는 값
int result = new MemberDao().insertMember(m); // Dao 값 리턴받기

if (result > 0) { // 성공했을 경우
	new MemberMenu().displaySuccess("회원가입 성공"); 
    // View 객체에 displaySuccess 메소드에서 실행될 것 지정해주기 
} else { // 실패했을 경우
	new MemberMenu(),displayFail("회원추가 실패");
}

참고)

1) jdbc driver 등록
Class.forName("oracle.jdbc.driver.OracleDriver"); //
ClassNotFoundException 발생 이유 2가지
(1) ojdbc6.jar 누락됐다거나, 잘 추가됐지만 오타가 있을 경우
(2) library가 없을 경우 - ojdbc6.jar 누락
=> ojdbc6.jar 추가하는 방법

<적용완료>

<JAVA - DB 연동 최종정리>

profile
새싹개발자

0개의 댓글