JDBC ?

이민경·2024년 3월 18일

JDBC

목록 보기
1/2

JDBC(Java DataBase Connectivity)

Java에서 DB에 연결할 수 있게 해주는 Java Programming API(Java에 기본 내장된 인터페이스)
JDBC는 java.sql 패키지에서 제공

💡 JDBC를 이용한 어플리케이션 만들때 필요한 것

  1. Java의 JDBC 관련 인터페이스
  2. DBMS (Oracle)
  3. Oracle에서 Java와 연결할 때 사용할 JDBC를 상속받아 구현할 클래스 모음(ojdbc10.jar 라이브러리)

그렇다면, JDBC를 이용하기 위해 단계별로 해야하는 것들에 대해서 알아보자!


📕 1단계

JDBC 객체 참조 변수를 선언해야한다(java.sql 패키지의 인터페이스로 import 해야함!)

📑 Connection
DB 연결 정보를 담을 객체

Connection conn = null;

🤷‍♀️ 여기서 잠깐
DB연결 정보는 DBMS 타입, 이름, IP, Port, 계정명, 비밀번호 저장을 말한다.

DBeaver의 계정 접속 방법과 유사하다고 할 수 있으며 이 연결 정보는 Java와 DB 사이를 연결해주는 통로 역할을 할 것이다.


📑 Statement
Connection을 통해 SQL문을 DB에 전달하여 실행하고 생성된 결과 (ResultSet, 성공한 행의 개수)를 반환(Java)하는데 사용되는 객체

Statement stmt = null;

📑 ResultSet
SELECT 질의 성공 시 반환되는데, 조회 결과 집합을 나타내는 객체

ResultSet rs = null;

📕 2단계

참조변수에 알맞은 객체를 대입한다.

1. DB 연결에 필요한 Oracle JDBC Driver 메모리에 로드하기

◾ 런타임 시점에 해당 경로의 클래스를 동적으로 로드함

Class.forName("oracle.jdbc.driver.OracleDriver");

▷ () 안에 작성된 클래스의 객체를 반환한다.
▶ 메모리에 객체가 생성되어지고 JDBC 필요 시 알아서 참조하여 사용되기에 생략해도 자동으로 메모리 로드가 진행된다! BUT, 명시적으로 작성하는 걸 권장하기에 적어주면 좋다!

2. 연결정보를 담은 Connection을 생성하기

◾ DriverManager 객체를 이용해서 Connection 객체를 만들어 이용

String type = "jdbc:oracle:thin:@"; ▷▶ JDBC 드라이버 종류
String ip = "localhost"; ▷▶ DB 서버 컴퓨터 IP // == 127.0.0.1 (loop back ip)
String port = ":1521"; ▷▶ 포트번호 // 1521 (기본값)
String sid =":XE"; ▷▶  DB 이름 // url == jdbc:oracle:thin:@localhost:1521:XE
String user = "kh_lmk"; ▷▶ 사용자계정
String pw = "kh1234"; ▷▶  비밀번호

❗ 단점 : 개인정보가 들어간 데이터를 넣기 때문에 보안상의 문제가 있으니 주의가 필요함 🤦‍♀️

객체를 만든 후 DriverManager에 전달하는데... 여기서?
DriverManager란 ❓ 메모리에 로드된 JDBC 드라이버를 이용해서 Connection 객체를 만드는 역할을 말한다.

conn = DriverManager.getConnection(type+ip+port+sid,user,pw);
 url == jdbc:oracle:thin:@localhost:1521:XE

3. SQL 작성하기

📣 주의 사항
JAVA에서 작성되는 SQL은 마지막에 ; 을 찍으면 안된다!

String sql ="SELECT EMP_ID, EMP_NAME, SALARY, HIRE_DATE FROM EMPLOYEE;";
String sql ="SELECT EMP_ID, EMP_NAME, SALARY, HIRE_DATE FROM EMPLOYEE";

4. Statement 객체 생성하기

◾ Connection 객체를 통해서 생성

stmt = conn.createStatement();

5. 생성된 Statement객체에 sql 을 적재하여 실행한 후 결과를 반환 받아와서 rs 변수에 저장하기

rs =stmt.executeQuery(sql);
//▷▶ executeQuery() : SELECT문 수행 메서드, ResultSet 반환

📕 3단계

SQL을 수행해서 반환 받은 결과 (ResultSet)를 한 행씩 접근해서 컬럼값 얻어오기

while(rs.next()) {
✔rs.next() : rs가 참조하고 있는 ResultSet 객체의 첫 번째 컬럼부터 순서대로 한행씩 이동하며 다음 행이 있을 경우, 
true, 없으면 false 반환![작성방법] : rs.get자료형("컬럼명")
				
	String empId = rs.getString("EMP_ID"); 
    //▶ "200", ➡ 현재 행의 "EMP_ID" 문자열 컬럼의 값을 얻어옴
				
	String empName = rs.getString("EMP_NAME"); //▶ "선동일"
				
	int salary = rs.getInt("SALARY"); //▶ 8,000,000
				
	//[java.sql.Date]
	Date hireDate = rs.getDate("HIRE_DATE"); //▶ YYYY-MM-DD 1990-02-06
				
	System.out.printf("사번 : %s / 이름 : %s / 급여 : %d / 입사일 : %s \n",
						empId, empName, salary, hireDate);
				
	//👀 java.sql.Date의 toString()은 yyyy-mm-dd 형식으로 오버라이딩 되어있음.
}

📕 4단계

사용한 JDBC 객체 자원 반환하기! (close())

▷ Connection, Statement, ResultSet 으로 실행했다면,
close할 때는 생성된 역순(ResultSet➡Statement➡Connection)으로 닫는 것을 권장함.

📣 finallytry~catch문 중 try부분에 작성!			

if(rs!= null) rs.close();
if(stmt!= null) stmt.close();
if(conn!= null) conn.close(); //▶ 각자 독립적인 객체들이기에 각각 다 닫아줘야 함!

👩‍💻 연습문제 time!


/* 
직급명, 급여를 입력받아 해당 직급에서 입력 받은 급여보다 많이 받는 사원의 이름, 직급명, 급여, 연봉을 조회하여 출력
✔ 단, 조회결과가 없으면 "조회 결과 없음" 출력!
✔조회 결과가 있으면 아래와 같이 출력!
[입력내용]
직급명 입력 : 부사장
급여 입력 : 5000000
[출력내용]
송종기 / 부사장 / 6000000 /72000000
노옹철 / 부사장 /3700000/44400000 
*/
		
		// Employee (empName, jobName, salary, annualIncome)
		
		
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		
		Scanner sc = new Scanner(System.in);
		
		try {
		
			System.out.print("직급명 입력 : ");
			String input1 = sc.next();
			
			System.out.print("급여 입력 : ");
			int input2 = sc.nextInt();
			
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url = "jdbc:oracle:thin:@localhost:1521:XE";
			String user = "kh_lmk";
			String pw = "kh1234";
			conn = DriverManager.getConnection(url,user,pw);
			
			String sql = "SELECT EMP_NAME, JOB_NAME, SALARY, SALARY*12 AS ANNUALINCOME"
					+ " FROM EMPLOYEE"
					+ " JOIN JOB USING(JOB_CODE)"
					+ " WHERE JOB_NAME = '" + input1 +"'"
					+ " AND SALARY > "+input2;
			
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql);
			
			List<Employee> list = new ArrayList<Employee>();
			
			while(rs.next()) {
				String empName = rs.getString("EMP_NAME");
				String jobName = rs.getString("JOB_NAME");
				long salary = rs.getInt("SALARY");
				long annualIncome = rs.getInt("ANNUALINCOME");
			
				list.add(new Employee(empName, jobName, salary, annualIncome));
			
			}
			
			if(list.isEmpty()) {
				System.out.println("조회 결과 없음");
			}else {
				for(Employee employee : list) {
					System.out.println(employee);
				}
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(rs != null) rs.close();
				if(stmt != null) rs.close();
				if(conn != null) rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

//입사일을 입력("2000-01-01") 받아 입력 받은 값 보다 먼저 입사한 사람의 이름, 입사일, 성별(M,F) 조회

		Scanner sc = new Scanner(System.in);
		
		Connection conn = null;
		Statement stmt =null;
		ResultSet rs = null;
		
		try {
			
			System.out.println("입사일 입력(YYYY-MM-DD) : ");
			String input = sc.next();
			
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url = "jdbc:oracle:thin:@localhost:1521:XE";
			String user = "kh_lmk";
			String pw = "kh1234";
			conn = DriverManager.getConnection(url,user,pw);
			
			
			String sql = "SELECT EMP_NAME 이름 , TO_CHAR(HIRE_DATE,'YYYY\"년\" MM\"월\" DD\"일\"')  입사일,"
					+ " DECODE(SUBSTR(EMP_NO,8,1),1,'M',2,'F') AS 성별"
					+ " FROM EMPLOYEE"
					+ " WHERE  HIRE_DATE <  TO_DATE('"+input+"')";
			
		stmt = conn.createStatement();
		rs=stmt.executeQuery(sql);
		
		List<Employee> list = new ArrayList<Employee>();
		
		while(rs.next()) {
			
			Employee emp = new Employee();
			
			emp.setEmpName(rs.getString("이름")); //조회 시 컬럼명이 "이름"
			emp.setHireDate(rs.getString("입사일")); //조회 시 컬럼명이 "입사일"
			emp.setGender(rs.getString("성별").charAt(0)); //조회 시 컬럼명이 "성별" / char 형태이기에 ! charaAt사용
			//JaVA의 char : 문자 1개의 의미
			//DB의 char : 고정길이 문자열 (== String)
			
			list.add(emp);
		}
			
		// 조회결과가 없는 경우
		if(list.isEmpty()) {
			System.out.println("조회결과 없음");
		}else {
			
			for(int i =0; i<list.size();i++) {
				System.out.printf("%02d) %s / %s / %c\n",i+1,list.get(i).getEmpName(), list.get(i).getHireDate(),list.get(i).getGender()   );
				
			}
		}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(rs !=null) rs.close();
				if(stmt != null) stmt.close();
				if(conn != null) conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
profile
풀스택 개발자

0개의 댓글