728x90

 

JDBC로 DB를 연결해서 DB연동 하고 있는 상태이고

반복적으로 사용되는 기능인 close와 transanction 같은 것들을 따로 Template클래스로 빼두어

import만하면 쉽게 사용할수 있게 코드가 구성되었고

db의 트랜잭션(commit & rollback)과

jdbc의 클래스 Connection, Statement, ResultSet의 close 기능 메소드를 만들었고

PreparedStatement는 Statement의 자식 클래스이기 때문에 다형성으로 인해 부모타입은 자식 객체를 다 받을 수 있으므로 해줄 필요 x

 

package common;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JDBCTemplate {


	// commit()
	public static void commit(Connection conn) {
		try {
			if(conn != null && !conn.isClosed()) { // conn.isClosed()은 SQLException 필요함
				conn.commit();
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	// rollback()
	public static void rollback(Connection conn) {
		try {
			if(conn != null && !conn.isClosed()) { // conn.isClosed()은 SQLException 필요함
				conn.rollback();
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	// Connection의 close처리
	public static void close(Connection conn) {
		try {
			if(conn != null && !conn.isClosed()) { // conn.isClosed()은 SQLException 필요함
				conn.close();
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	// ResultSet의 close처리
//	public static void close(ResultSet rset) { 
//		// close(ResultSet rset)만 적었는데 위의 close와 다르게 에러 안나는 이유
//		// 답 : 오버로딩이 적용되었기 때문
//	}
	public static void close(ResultSet rset) { 
		try {
			if(rset != null && !rset.isClosed()) { // conn.isClosed()은 SQLException 필요함
				rset.close();
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	// Statement의 close처리
	public static void close(Statement stmt) { 
		try {
			if(stmt != null && !stmt.isClosed()) {
				stmt.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	
}

 

728x90
반응형
728x90

 

MVC 로직 작동 순서 설명 (feat. JDBC 메뉴구현)

메뉴파일 MVC패턴 설명 with JDBC & oracle

 

1.run파일에서 뷰의 메뉴 메소드 호출

(view를 기준으로 하나씩 구현해가면 덜 헷갈린다)

package com.kh.run;
import com.kh.view.Menu;

public class Run {
	public static void main(String[] args) {
		**new Menu().mainMenu();**
	}
}

 

 

2.뷰의 메뉴 메소드에서 사용자에게 메뉴 번호 입력받아 해당 번호를 실행하기 위해 콘트롤러에게 해당 번호 메소드 요청

public class Menu {
	public void mainMenu() {
	Employee**Controller ec** = new EmployeeController();
	do { 			
			System.out.println("====================");
			System.out.println("[Main Menu]");
			System.out.println("1.전체 사원 정보 조회");	
			// ... 
	switch(user) {
			case 1: **ec.selectAll()**; break;
			case 2: break;
			// ...
			default: System.out.println("잘못 입력")	
			}
		} while(user != 0); 

 

 

3.컨트롤러에서 DAO 메소드를 호출한다.(후에 결과값 받아옴)

목적이 DB(오라클)에서 전체 사원정보 조회이기에 자바랑 sql 오라클을 연결해서 받아 올 수 있게 DAO에서 메소드를 호출한다

DAO(Date Access Object) : 외부 데이터 저장공간과 연결하는 역할

세부설명 : DB의 data에 접근하기 위한 객체로 직접 DB에 접근하여 데이터를 삽입, 삭제, 조회 등 조작할 수 있는 기능을 수행한다.

package com.kh.controller;

public class EmployeeController {
public void selectAll() {
		**empDAO.selectAll()**; // DAO에서 메소드를 호출
	}

 

 

4.DAO에서 jdbc 드라이버 연결 및 받아온 데이터를 리턴함

  • 주의사항 : 리턴할 때 리턴하는 데이터의 타입을 보고 해당 메소드( selectAll() )의 반환타입을 리턴하는 데이터로 수정해준다. 보통은 void로 되어있을 것이다.
package com.kh.model.dao;
public class EmployeeDAO {
	public **ArrayList<Employee>** selectAll() {
		// jdbc 드라이버 연결 및 자료 받아오기
		**return list**;
  }	
}

 

 

5.위의 3번에서 empDAO.selectAll(); 이 코드가 필요에 의해 DAO를 호출했기에 받아온 값을 다시 넣어줘야한다 .

그리고 사용자에게 받아온 데이터의 결과값을 보여주기 위해 뷰의 메소드를 호출한다

package com.kh.controller;

public class EmployeeController {
public void selectAll() {
		**ArrayList<Employee> list** = empDAO.selectAll(); 
		
		// list가 비어있을 때 = 사원이 없을 때
		if(list.isEmpty()) {
			menu.displayError("조회 결과가 없습니다.");
		}else {
		// list가 비어있지 않을 때 = 사원 존재할 때
			**menu.selectAll(list);** // DAO에서 받아온 list의 값이 존재하니 받아온 데이터를 넘겨줌
		}
	}

 

 

6.DAO에서 받아온 전체사원정보 데이터를 콘트롤러에서 menu.selectAll(list); 코드를 통해 아래의 뷰 selectAll()메소드로 보내주었고, 받아온 데이터의 형식이 리스트에 여러 행이 존재하기에 for문 돌려서 한 줄 씩 받아와서 출력이 되도록 println() 해준다

package com.kh.view;
public class Menu {
	public void mainMenu() {
		// ...
	}

	public void **selectAll**(ArrayList<Employee> list) {
			for(int i = 0; i < list.size(); i++) {
				System.out.println(list.get(i));
			}
	}
}

 

7.다른 메뉴의 기능 구현할려면 2번으로 돌아가 do while문 안에 switch문의 case에서 컨트롤러를 호출하는 메소드를 기술하고 컨트롤러에 가서 해당 메소드를 생성하는 것으로 이어가면 된다

 

 

요약

V → C → M

V ← C ← M

 

1.run파일에서 뷰 메뉴 메소드 호출

2.실행 할 기능의 컨트롤러 메소드 호출

3.컨트롤러에서 DAO 메소드 호출 for DB연결 및 데이터 가져오기

4.호출된 DAO 메소드에서 jdbc로 db에 연결 및 받아온 데이터를 리턴해준다.

5.컨트롤러에서 필요에 의해 값을 받아오기 위해 DAO 메소드를 호출했으니, 호출요청한 코드에 DAO에서 받아온 데이터를 넣어준다

그리고 사용자에게 받아온 데이터의 결과값을 보여주기 위해 뷰의 메소드를 호출하고 호출하면서 DAO에서 받아온 데이터를 같이 보내준다

6.DAO에서 컨트롤러를 거쳐 받아온 데이터를 사용자에게 보여주기 위해 해당 뷰 메소드에서 받아온 데이터를 출력할 수 있게 데이터처리하고 출력하면 된다

 

JDBC 메뉴구현 : MVC 로직 작동 순서 설명 (notion.site)

 

JDBC 메뉴구현 : MVC 로직 작동 순서 설명

A new tool for teams & individuals that blends everyday work apps into one.

furtive-coelurus-447.notion.site

 

 

 

728x90
반응형
728x90

JDBC(Java DataBase Connectivity)

자바에서 데이터베이스에 접근할 수 있게 해주는 API

JDBC = JAVA + database

     - java 기능구현

     - database 데이터 저장

 

 

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver

이 메세지가 뜨는 원인은

  1. 드라이브명 쪽 오타
  2. 해당 라이브러리를 넣지 않아서

아래와 같이 JDBC 구현 코드를 다 잘쓴다 하더라도 에러가 발생한다

 

ojdbc 라이브러리를 이클립스에 로드시켜야한다

ojdbc 라이브러리 위치(11g버젼 기준)

C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib

11g 버젼은 ojdbc6 사용

12버젼 이상은 ojdbc8사용

 

이클립스, 라이브러리 적용방법

프로젝트 우클릭 properties - java build path - Libraries tap으로 이동 - 우측에 Add External JARs... 클릭 - 위의 라이브러리 위치의 ojdbc6 클릭 - apply 클릭

 

잘 적용되었는지 확인 방법

적용이 잘 됬으면 아래 처럼 Referenced Libraries 탭에 ojdbc6.jar가 추가된 것을 확인 할 수 있다

 

728x90
반응형
728x90

 

옆 클래스 파일로 빠르게 넘어가고 싶다면?

일일히 마우스로 클릭해주는게 불편하다면?

 

옆페이지로 넘겨주는 기능!

alt + page up

alt + page down

단축키로 빠르게 왔다갔다 할 수 있다

근데 간격이 너무 넓어서 마우스 손을 가져와서 써야해서 불편하니  단축키를 바꾸고 싶으면 아래를 참고하자

 

 

 

 

상단 window - preferences 클릭

keys로 검색해도 되고 general - Editors - Keys로 들어가서

아래와 같이 previous tab과 next tab검색

 

위의 이미지에서 Binding 하이라이트 된 곳에 원하는 단축키를 지정하고 편하게 쓰자

다만 기존 단축키와 겹칠 수 있으니 너무 쉽거나 자주 쓰는 단축키 기능과 겹치지 않게 조심하자

 

 

필자는

previous tab(이전 탭) 이동은 shift + 3

next tab(다음 탭) 이동은 shift + 4

로 변경했다

 

728x90
반응형
728x90

 

JDBC 연결 관련 클래스 5가지

1)Class.forName(”JDBC드라이버명”)

사용할 Database의 JDBC 드라이버 지정하는 역할

2)DriverManager

연결할 계정 정보 지정

3)Connection

데이터베이스에 연결된 실질적인 통로

4) Statement / PreparedStatement

쿼리를 전달하는 역할

5)ResultSet

SELECT문에 대한 결과값을 담고 있는 객체

 

 

package com.kh.model.dao;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import com.kh.model.vo.Employee;

public class EmployeeDAO {
	
	
	// 목표 : 전체 사원 정보 조회
	public ArrayList<Employee> selectAll() {
		ArrayList<Employee> list = null;
		Connection conn = null;
		Statement stmt =  null;
		ResultSet rset =  null;
		
		// JDBC 드라이버 등록
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver"); // 오라클 드라이버 풀네임. 버젼마다 약간다름
			conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:xe", "SCOTT", "qrwe"); // 디벨로퍼에서 계정등록 시에 세부정보에서 포트번호,SID에 있는걸로 맞추면된다. 19c는 orcl일 것임. 
			
//			System.out.println(conn); // 주소값 반환 oracle.jdbc.driver.T4CConnection@f2a0b8e ← 모든 컴퓨터가 같게 뜬다
			
			String query = "SELECT * FROM EMP"; // SCOTT계정의 테이블정보 쿼리문 적기 // 주의 : 세미콜론 뒤에 안붙인다
			stmt = conn.createStatement();  	// java.sql.statement 임포트
			stmt.executeQuery(query); 			// select문 - executeQuery() - 객체 ResultSet 
			rset = stmt.executeQuery(query); 	// 과정설명 요약 : query에서 작성한 쿼리문을  stmt.executeQuery(query)에서 보내고, ResultSet rset = stmt.executeQuery(query)에서 결과를 반환 받음
			list = new ArrayList<Employee>(); // 순서 지키기 위해 ArrayList 사용
			while(rset.next()) { 	// ResultSet.next() : 다음 행이 존재하면 true반환, 없으면 false반환
				
				int empNo = rset.getInt("EMPNO"); // ResultSet 안에 있는 메소드 getInt() // SCOTT계정 EMP테이블의 empno컬럼 데이터 가져오기
				String empName = rset.getString("ENAME");
				String job = rset.getString("JOB"); 	// 컬렴명 소문자도 괜찮. 괄호 안 대소문자 관계x
				int mgr = rset.getInt("MGR");  
				Date hireDate = rset.getDate("HIREDATE"); 
				int sal = rset.getInt("SAL");
				int comm = rset.getInt("COMM");
				int deptNo = rset.getInt("DEPTNO");		// model.vo로 데이터를 넘기는 코드
				Employee e = new Employee(empNo, empName, job, mgr, sal, comm, deptNo); // empNo~deptNo까지의 데이터를 다 담아서 한 뭉텅이로 만든 코드
				
				list.add(e);  // ArrayList<Employee> list에 Employee e 객체를 담음
				
			}
			System.out.println(list);			// 전체 사원 14명의 전체 정보를 가져옴 
 
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				rset.close();
				stmt.close(); 
				conn.close(); 
			} catch (SQLException e) {
				e.printStackTrace();
			} 
		}
		
		return list; // view로 데이터를 보내는 코드 
		
		// model.vo로 가서 ArrayList<Employee> list에 값을 받는다고 코드 지정해줄 것
		
	}
	
	
}
728x90
반응형
728x90

 

인코딩 설정 UTF-8

window - general - editors - text editors- spelling

인코딩 설정은 워크스페이스 당 한번만 하면 된다

 

Default나 Other 둘 중 UTF-8로 되어있는 거에 체크하면 된다

 

preference 아래 검색란에 encoding치고 General - Workspace

하단에 Text file encoding탭에 Other에서 UTF-8에 두고 체크

 

마찬가지로 workspace 아래 다른 탭 CSS, HTML, JSP, XML에도 들어가서 UTF-8을 선택하고 apply and close 하자

 

 

여기까지 했으면 새로운 프로젝트나 파일을 만들 때 UTF-8 인코딩이 다 적용된다

근데 이미 만든 프로젝트 파일 혹은 개별 파일들은...?

또는 따로 필요에 의해 일부만 변경하고 싶을 때 사용 하는 방법

 

왼쪽 Project Explorer에서 변경하기를 원하는 파일or프로젝트 파일 위에서 우클릭 - properties - resource

properties 열면 바로 보이는 resource에서

 

 

 

 

728x90
반응형
728x90

 

model.VO

Override toString() + setter/getter

 

package MVC.model.vo;
import java.sql.Date;

public class pModelVo07 {
//  VO : Vaule Object
//		 데이터를 잠시 담아두는 ‘임시 저장공간’
//    	 변수로써 사용
//	 	 Read-Only속성을 값 오브젝트
//   	  자바에서 단순히 값 타입을 표현하기 위해 불변 클래스(Read-Only)를 만들어 사용

	private int empNo; // 사번
	private String empName; // 이름
	private String job; // 직책
	private int mgr; // 직속 상사(manager)
	private Date hireDate; // java.sql.Date // 고용일
	private int sal; // 급여
	private int comm; // 커미션(인센티브)
	private int deptNo; // 부서번호

	
	public pModelVo07() {}
	public pModelVo07(String job, int sal, int comm) {
		this.job = job;
		this.sal = sal;
		this.comm = comm;
	}
	public pModelVo07(int empNo, String job, int sal, int comm) {
		this(job, sal, comm);
		this.empNo = empNo;
	}
	public pModelVo07(int empNo, String empName, String job, int mgr, int sal, int comm, int deptNo) {
		this(job,sal,comm);
		this.empNo = empNo;
		this.empName = empName;
		this.mgr = mgr;
		this.deptNo = deptNo;
	}
	public pModelVo07(int empNo, String empName, String job, int mgr, Date hireDate, int sal, int comm, int deptNo) {
		this(job,sal,comm);
		this.empNo = empNo;
		this.empName = empName;
		this.mgr = mgr;
		this.deptNo = deptNo;
		this.hireDate = hireDate;
	}
	
	public int getEmpNo() {
		return empNo;
	}
	public String getEmpName() {
		return empName;
	}
	public String getJob() {
		return job;
	}
	public int getMgr() {
		return mgr;
	}
	public Date getHireDate() {
		return hireDate;
	}
	public int getSal() {
		return sal;
	}	
	public int getComnn() {
		return comm;
	}
	public int getDeptNo() {
		return deptNo;
	}
	
	public void setEmpNo(int empNo) {
		this.empNo = empNo;
	}
	public void setEmpName(String empName) {
		this.empName = empName;
	}
	public void setMgr(int mgr) {
		this.mgr = mgr;
	}
	public void setHireDate(Date hireDate) {
		this.hireDate = hireDate;
	}
	public void setSal(int sal) {
		this.sal = sal;
	}
	public void setComm(int comm) {
		this.comm = comm;
	}
	public void setDeptNo(int deptNo) {
		this.deptNo = deptNo;
	}
	
	
	@Override
	public String toString() {
		return empNo+" / "+empName+" / "+job+" / "+mgr+" / "+hireDate+" / "+sal+" / "+comm+" / "+deptNo+" / ";
	}
	
}
728x90
반응형
728x90

 

문자 기반 스트림

FileWriter/FileReader 클래스

 

메소드 

write,append,close

import java.io.FileReader;
import static java.util.Collections.*;


import java.io.FileWriter;
import java.io.IOException;
public class practice_everyday08 {
	public static void main(String[] args) throws IOException {
		
		// 문자 기반 스트림
		// FileReader
		// FileWriter
		
		FileWriter fw = new FileWriter("D:\\file\\file2\\first.txt");
		fw.write("initiate\n");
		fw.append("2\n");
		char[] cArray = {'c','h','e','e','r'};
		char[] sArray = {'u','p'};
		fw.write(cArray);
		fw.write(sArray);
		fw.close();
		
		FileReader fr = new FileReader("D:\\file\\file2\\first.txt");
		int i;
		while((i=fr.read()) != -1) {
			System.out.print((char)i);
		}
		fr.close();
		
	}	
}

 

728x90
반응형
728x90

 

로그인 코드 연습

 

public class practice_everyday03 {

	public static void main(String[] args) {

		// 전체 유저 목록
		// 현재유저 아이디 암호 입력
		// 유저 목록에 있는 체크(반복문)
		// 로그인 완료 메세지
		
		String[][] users_all = {
				{"choi","1111"},
				{"kim","2222"},
				{"lee","3333"}
		};
		String[][] user_current = {
				{args[0]},
				{args[1]} // id pw 따로 받아야하나?		
		};
		
		
		boolean userLogin = false;
		for (int i = 0; i < users_all.length; i++) { // 2차원 배열이지만 안에 배열 갯수를 세온다
//			System.out.println(users_all[i][0]);
//			System.out.println(users_all[i][1]);
//			System.out.println(user_current[i]); // 디버깅 중 출력값 무엇?? [Ljava.lang.String;@6504e3b2 ??
												// current의 배열길이는 전체 두개인데 i변수는 all의 길이이므로 인덱스번호가 안맞아서 오류
//			String[] user_current_IdPw = user_current;
//			if (user_current_IdPw[0].equals(users_all[i][0]) && // 계속 로그인실패만 뜨는데 뭐가 문제지?
//				user_current_IdPw[1].equals(users_all[i][1])	
//						) {
//			if (user_current[0].equals(users_all[i][0]) &&  // 계속 로그인실패만 뜨는데 뭐가 문제지?
//				user_current[1].equals(users_all[i][1])		
//					) {
				userLogin = true;
				break;
			};
//		};
			
		
		if (userLogin) {
			System.out.printf("로그인 성공%n환영합니다");
		} else {
			System.out.println("로그인 실패");
		}
		
	}

}

 

 

728x90
반응형
728x90

String 클래스

 

String Class의 메소드들

1)charAt ()

charAt(int index):char

 

2) concat()

concat(String str):String
원래 문자열 끝에 매개변수로 들어온 값을 이어붙인 문자열 반환

 

3) equals()

equals(Object anObject):boolean

 

4)substring()

substring(int beginIndex):String
해당 인덱스 넘버부터 문자열 시작
substring(int beginIndex, int endIndex):String

 

5)replace()

replace(char oldChar, char newChar):String

 

 

public class practice_everyday01 {
	public static void main(String[] args) {	
		
		// String class : representative methods
		String str = "힘을 내라";
		
		// 1)charAt ()
		// charAt(int index):char
		char cheer = str.charAt(0);
		System.out.println("1."+cheer); // 힘
		
		// 2) concat()
		// concat(String str):String
		// 원래 문자열 끝에 매개변수로 들어온 값을 이어붙인 문자열 반환
		String cstr = str.concat(" cheer up");
		System.out.println("2."+cstr );
		
		
		// 3) equals()
		// equals(Object anObject):boolean
		System.out.println("3."+str.equals("equal"));
		
		// 4)substring()
		// substring(int beginIndex):String
		// 해당 인덱스 넘버부터 문자열 시작
		// substring(int beginIndex, int endIndex):String
		// A to B 사이의 문자열 일부 반환
		
		System.out.println("4.1."+str.substring(0,3));
		System.out.println("4.2."+str.substring(2));
		
		
		// 5)replace()
		// replace(char oldChar, char newChar):String
		
		System.out.println("5."+str.replace('힘','손'));
	}	
}

 

 

728x90
반응형

+ Recent posts