본문 바로가기

Java + Oracle

[210928] db 연동 연습문제

전날 강의 내용 리뷰

 

Database가 연결 된 상태를 계속 유지하면 안 된다.

연결이 다 되었으면 연결 종료해서 자원을 반납하여야 한다.

항상 연결이 된 상태를 유지하는 게 아니라 연결해서 필요한 정보를 가져다가 사용을 다 했으면 연결을 끊어줘야 한다. (close 작업)

 

close 작업은 ResultSet부터 닫는다.

ResultSet부터 닫고 Statement를 닫고 OracleConnection(클라우드용) 또는 Connection(로컬용)를 닫는다.

처음에는 Connection먼저 열고 Statement 활성화 시키고 ResultSet 순차적으로 만드는데 닫을 때는 반대이다.

 

열림 순서 : OracleConnection 또는 Connection ->  Statement -> ResultSet 

닫힘 순서 : ResultSet -> Statement -> OracleConnection 또는 Connection

 

연결해서 조회할 내용을 처리하는 일련의 공통된 과정이다.

여기서 달라지는 것은 어떠한 쿼리를 전송할 것이냐, (오라클에서 쿼리 가져올 때는 세미콜론 ' ; ' 빼고 가져온다.)

ResultSet을 해당 쿼리에 맞게 어떻게 내부 처리를 할 것이냐만 차이가 있다.

미리 연결 정보 생성하고 데이터베이스 연결하고 스테이트먼트 생성하고 이제 쿼리가 필요할 때 내가 원하는 쿼리 정리해서 실행될 수 있도록, 그리고 그 정리된 내용대로 내부 처리 진행될 수 있도록 두 작업만 수정하면 된다.

 

직접 구현 해보는 게 중요하다 (제대로 DB연결이 되었는지 확인하고 싶다면  간단한 쿼리문을 가져와서 실행 해 본다. 만일 작성한 쿼리의 문자열에 문제가 있다면 DB연결은 잘 됐더라도 실행이 정상적으로 안 될 수도 있으므로 찾아서 수정해야 한다.)

 


 

Q. 급여가 8000 이상인 사원을 조회한다. 조회하는 컬럼은 이름, 급여액, 커미션을 조회하고
조회한 결과는 리스트 컬렉션에 담아서 출력하도록 한다.

 - 클래스를 만들어서 리스트에 추가
 - 맵 컬렉션을 사용하여 리스트에 추가 (문자열 변환해서 다 저장, 사용시에도 변환해야 해서 번거로움)

 - 클래스를 만들어서 리스트에 추가

package com.kh.exam1; 

import java.io.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

import com.db.conn.OracleConnect;

class Employee {
	
	private String name;
	private int salary;
	private double commission;
	
	//인스턴스 생성자 없이 기본생성자로만 하려고 주석 처리
//	public Employees(String name, int salary, double commission) {
//		this.name = name;
//		this.salary = salary;
//		this.commission = commission;
//	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getSalary() {
		return salary;
	}

	public void setSalary(int salary) {
		this.salary = salary;
	}


	public double getCommission() {
		return commission;
	}

	public void setCommission(double commission) {
		this.commission = commission;
	}

	@Override
	public String toString() {
		return "Employees [name=" + name + ", salary=" + salary + ", commission=" + commission + "]";
	}

} 


public class Sample2 {

	public static void main(String[] args)  {
		String query = "SELECT FIRST_NAME || ' ' || LAST_NAME\n"
				+ "     , SALARY\n"
				+ "     , NVL(COMMISSION_PCT, 0)\n"
				+ "  FROM EMPLOYEES\n"
				+ " WHERE (SALARY * (1 + NVL(COMMISSION_PCT, 0))) >= 8000";
					//연봉 괄호 묶지 않으면 오류 남 우와...
					//개행문자를 넣지 않고 쿼리를 작성한다면 반드시 띄어쓰기로 각각의 코드 분리해야 한다
		
		// Database에 연결된 객체 정보까지만 생성자를 통해 만든다.
		OracleConnect oc = null;
		try {
			oc = new OracleConnect();
		
		// 연결된 커넥션을 통해 SQL을 전송할 수 있도록 미리 Query 문자열을 설정한다.
		oc.setQuery(query);
		
		// 설정된 Query 문자열로 SQL 질의문이 전송되도록 하며, 결과물로 ResultSet을 반환받는다.
		ResultSet rs = oc.execute();
		
		// 반환 받은 데이터를 반복문을 사용하여 출력한다.

		List<Employee> eList = new LinkedList<Employee>();
	//인스턴스 생성자 안 만들고 하는 것(선생님)
		while(rs.next()) {
			Employee e = new Employee();
			e.setName(rs.getString(1));
			e.setSalary(rs.getInt(2));
			e.setCommission(rs.getDouble(3));
			eList.add(e);
		}
		System.out.println(eList);
	
	//생성자 만들어서 한 것(내가)	
//		String name;
//		int salary;
//		double commission;
		
//		while(rs.next()) {
//			name = rs.getString(1);
//			salary = rs.getInt(2);
//			commission = rs.getDouble(3);
////확인용   	System.out.println(name + " " + salary + " " + commission);
//			
//			eList.add(new Employees(name, salary, commission));
//		}
//		for(Employees e : eList) {
//			System.out.println(e);		
//		}
		
		// 모든 작업 완료 후 객체를 반환한다.
			rs.close();
			oc.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

※ Java 에서 쿼리문 작성시 유의 사항

1. WHERE 절의 괄호를 제대로 묶지 않으면 오류가 발생한다.

2. 쿼리문 작성시 개행문자를 넣지 않고 쿼리를 작성한다면 반드시 띄어쓰기로 각각의 코드를 분리하여야 한다. 

 

 

 

데이터 베이스 조회 결과 파일로 출력하기

Q. 리스트에 담긴 객체를 콘솔 출력이 아닌 파일로 출력하는 것으로 변경한다.(파일 입출력 활용)

조건 1 : 파일명은 Employee.txt
조건 2 : fileWriter 스트림 객체에 BufferedWriter 보조 스트림을 사용
package com.kh.exam1; 

import java.io.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

import com.db.conn.OracleConnect;

class Employee {
	
	private String name;
	private int salary;
	private double commission;
	
	//생성자 없이 기본생성자로만 하기
//	public Employees(String name, int salary, double commission) {
//		this.name = name;
//		this.salary = salary;
//		this.commission = commission;
//	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getSalary() {
		return salary;
	}

	public void setSalary(int salary) {
		this.salary = salary;
	}

	public double getCommission() {
		return commission;
	}

	public void setCommission(double commission) {
		this.commission = commission;
	}

	@Override
	public String toString() {
		return "Employees [name=" + name + ", salary=" + salary + ", commission=" + commission + "]";
	}

} 


public class Sample2 {

	public static void main(String[] args)  {
		String query = "SELECT FIRST_NAME || ' ' || LAST_NAME\n"
				+ "     , SALARY\n"
				+ "     , NVL(COMMISSION_PCT, 0)\n"
				+ "  FROM EMPLOYEES\n"
				+ " WHERE (SALARY * (1 + NVL(COMMISSION_PCT, 0))) >= 8000";
					//연봉 괄호 묶지 않으면 오류 남 우와...
					//개행문자를 넣지 않고 쿼리를 작성한다면 반드시 띄어쓰기로 각각의 코드 분리해야 한다
		
		// Database에 연결된 객체 정보까지만 생성자를 통해 만든다.
		OracleConnect oc = null;
		try {
			oc = new OracleConnect();
		
		// 연결된 커넥션을 통해 SQL을 전송할 수 있도록 미리 Query 문자열을 설정한다.
		oc.setQuery(query);
		
		// 설정된 Query 문자열로 SQL 질의문이 전송되도록 하며, 결과물로 ResultSet을 반환받는다.
		ResultSet rs = oc.execute();
		
		// 반환 받은 데이터를 반복문을 사용하여 출력한다.

		List<Employee> eList = new LinkedList<Employee>();
	//클래스 생성자 안 만들고 하는 것 (선생님)
		while(rs.next()) {
			Employee e = new Employee();
			e.setName(rs.getString(1));
			e.setSalary(rs.getInt(2));
			e.setCommission(rs.getDouble(3));
			eList.add(e);
		}
		System.out.println(eList);
//확인용	System.out.println("eList.toString()" + eList.toString());
		
		// 콘솔 출력이 아닌 파일로 출력하는 것으로 변경한다
		// 파일명은 Employee.txt
		// fileWriter 스트림 객체에 BufferedWriter 보조 스트림을 사용		
		FileWriter fw = new FileWriter("./Employee.txt");	
		//확장자를 .csv로 작성해서 아래의 bw.write 괄호 안의 "|" 문자를 모두 ","로 변경하면 엑셀파일로 저장된다.
		BufferedWriter bw = new BufferedWriter(fw);
		bw.write("NAME|SALARY|COMMISSION\r\n"); // 개행 문자 포함해서 작성하거나
												// bw.newLine(); 작성
		for(Employee e : eList) {
			//bw.write(e.toString()+"\r\n");			
			bw.write(e.getName() + "|" + e.getSalary() + "|" + e.getCommission() + "\r\n");
		}
		
		bw.close();
		fw.close();
		
		// 모든 작업 완료 후 객체를 반환한다.
			rs.close();
			oc.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

CSV 파일로 저장