java JDBC

개미Coder
|2024. 5. 29. 14:08
반응형

 

한 줄 요약: 오라클 SQL을 Java에서 호출하는 방법

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Main_DBPractice {

	static {
		// 반드시 ojdbc14.jar 드라이버 초기화 해야한다. static으로 가장 먼저 실행
		try {
			Class.forName("oracle.jdbc.OracleDriver");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws SQLException {

		// 1. Connection 얻어오기
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String user = "test";
		String pwd = "test";
		// 커넥션에 변수로 url과 id,pwd를 넣어준다.
		Connection conn = DriverManager.getConnection(url, user, pwd);

		// 2. Statement 얻어오기 : SQL 명령을 처리하는 객체
		Statement stmt = conn.createStatement();

		// 3. ResultSet 조회하기 : 조회결과를 관리하는 객체
		ResultSet rs = stmt.executeQuery("select * from sawon");
		// 가져온 데이터 반목문 next()를 통해서 조회해주기
		// rs.next()를 통해 다음 결과가 데이터 영역인지 확인해준다.
		while(rs.next()) {
			int sabun = rs.getInt("sabun");
			String saname = rs.getString("saname");
			String sasex = rs.getString("sasex");
			int deptno = rs.getInt("deptno");
			String sajob = rs.getString("sajob");
			Date sahire = rs.getDate("sahire");	
			System.out.printf("%d -- %s -- %s -- %d -- %s\n",sabun,saname,sasex,deptno,sajob);
		}


		// 역순으로 닫아주기 (connection은 무한 생성이 아니므로, 닫아주어야 한다)
		rs.close();
		stmt.close();
		conn.close();

	}
}

 

 

 


 

 

 

자바의 언어랑 데이터베이스 언어는 다르기 때문에 Driver를 통해서 연결시켜준다.

 

 

Connection으로 데이터를 서로 공유해주기 위해서 연결해준다.

쉽게 얘기하자면, 친구와 친구끼리 연락을 하는데에 필요한 통신 역할을 해준다.

 

Statement는 명령처리 객체로써, SQL문을 처리해준다.

 

- url 경로는 이곳에 있다.

 

 

 

 


 

 

 

자바랑 데이터베이스랑 본격적으로 연결해보자

 

 

 

- 이제 실전으로 들어가자, 프로젝트를 새로만든다. ojdbc14.jar를 넣는다.

 

 

Connection

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

public class MyMain_TestJDBC1 {
	
	// 초기화 작업(start하기전에 시동을 켜놓은 상태) - 진짜 바로먼저 출발 차량 static 모델
	static {
		//System.out.println("0. 내가 먼저 실행돼!!");
		// 출결 프로그램 마냥 장시간 사용하지 않으면 gc(가비지컬렉터)에서 얘를 heap영역에서 쓰레기통으로 처리해버린다.
		//new OracleDriver();
		
		// 단 ojdbc14.jar 반드시 드라이버 초기화 해야한다.
		// ojdbc60.jar  ojdbc80.jar 버전에서는 아래 초기화식 생략가능하다.
		try {
			// 여기에 작성된 클래스가 없을 경우도 있기에, 예외처리
			Class.forName("oracle.jdbc.OracleDriver");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	public static void main(String[] args) throws Exception {
		//System.out.println("1. 내가 제일먼저 실행돼!!");
		
		// 1. Connection 얻어오기
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String user = "test";
		String pwd = "test";
		
		Connection conn = DriverManager.getConnection(url, user, pwd);
		System.out.println("---success connect---");
        // Oracle의 Connection의 연결권한은 무한개가 아니다. connection을 닫아서 반납해야 한다.
		// connection 닫기
		conn.close();
	}
}

 

 

Statement

- 테이블생성(DDL), 테이블삭제(DDL)

- 테이블이 이미 생성되어있으면 error, 삭제할 테이블이 없으면 error

- executeUpdate 할 때 변수명을 넣어줘도 되고 직접 입력할 코드를 넣어주는것도 가능하다.

 

select : executeQuery(sql);
select 외 모든명령 : executeUpdate(sql);

 

Statement에서 excuteUpdate 하는 예시(DDL 테이블생성, DML 데이터생성)

// 2. Statement 얻어오기 : SQL명령 처리하는 객체
Statement stmt = conn.createStatement();

// 테이블생성(DDL)
String sql = "create table AAA(no int)";
stmt.executeUpdate(sql);

// 테이블삭제(DDL)
stmt.executeUpdate("drop table AAA");

// 데이터 insert(sungtb)
int res = stmt.executeUpdate("insert into sungtb values(6,'육길동',1,2,3)");
System.out.println(res); // result = 1

// 데이터 delete : DML
int res = stmt.executeUpdate("delete from sungtb where no = 6");
System.out.println(res); // result = 3(위에서 육길동 데이터가 3번 저장되었다면)

// 데이터 update : DML
int res = stmt.executeUpdate("update sungtb set kor=100,eng=100,math=100 where no = 1");
System.out.println(res);

...

stmt.close();

 

 

 

조회하기

Statement에서 excuteQuery하는 예시( excuteQuery의 로직)

ResultSet rs는 결과행을 관리해주는 객체이다.

 

- rs는 처음부터 deptno 10을 바로 가리키는 것이 아니라 BOF(Begin Of File)을 가리키고 시작한다.

rs.next()는 데이터를 가리키고 있으면 (dept 10, 20 ... 50) true 값을 반환한다. (rs.next 는 boolean형)

rs.next()를 통해 다음값이 EOF(End Of File)를 가리키고 있다면, 값은 false로 while문이 종료된다.

 

// 3. 조회 : ResultSet <- 조회결과를 관리하는 객체
ResultSet rs = stmt.executeQuery("select * from dept");
System.out.println(rs); // result : oracle.jdbc.driver.OracleResultSetImpl@2eda0940

// 전체조회
while(rs.next()) { // rs.next()결과가 데이터 영역이냐?
    // 현재 rs가 가리키는 행에 컬럼정보 읽어오기
    int deptno = rs.getInt("deptno");
    String dname = rs.getString("dname");
    String loc = rs.getString("loc");
    // DB Type과 상관없이 String형으로 읽어올 수 있다.
    String str_no = rs.getString("deptno");

    System.out.printf("%d-%s-%s\n",deptno,dname,loc);
}

rs.close();

 

StringBuffer로 받아줄 수도 있다.  오라클 SQL에서 처리해주면 되긴하는데, 외부에서 수정하는 경우, String을 일일이 추가하면서 하기에는 너무 번거로울 수 있다.

StringBuffer sb = new StringBuffer("select * from dept");
sb.append("where deptno!=10");
sb.append("order by deptno desc");
ResultSet rs2 = stmt.executeQuery(sb.toString());
StringBuffer sb = new StringBuffer("select * from gogek_view3 ");
sb.append("where substr(goaddr,1,2) = (select substr(goaddr,1,2) from gogek_view3 where goname = '류민') ");
sb.append("order by gobun ");
ResultSet rs = stmt.executeQuery(sb.toString());


while(rs.next()) {
    int gobun = rs.getInt("gobun");
    String goname = rs.getString("goname");
    String goaddr = rs.getString("goaddr");
    int godam = rs.getInt("godam");
    String gojumin = rs.getString("gojumin");
    String birthyear = rs.getString("birth_year");	
    System.out.printf("%d -- %s -- %s -- %d -- %s -- %s \n",gobun,goname,goaddr,godam,gojumin,birthyear);
}

 

- 인덱스 호출해서 next()를 받는 경우 (안씀)

ResultSet rs = stmt.executeQuery("select deptno,loc,dname from dept");
// 이렇게 컬럼명을 호출하면 해당 index와 다르다.
    // 전체조회
    while(rs.next()) { // rs.next()결과가 데이터 영역이냐?
        // 방법2) 이건 쓰지말어!!
        int deptno = rs.getInt(1);
        String dname = rs.getString(2);
        String loc = rs.getString(3);
        System.out.printf("%d-%s-%s\n",deptno,dname,loc);
    }

 

 

 

 


 

Statement와 PreparedStatement(사전에 준비해놓다)의 차이

 

Statement는 문법체크를 하고 (구분분석 Parsing) 또 다른 where 조건문이 들어오면, 문법체크를 또 실행한다.

(비효율적이라는 뜻 : 문법체크 1번당 1초시, 100번 실행시 100초 소모)

 

 

 

 

Statement에서 " or 1=1" 이라는 true 값을 넣어버리면 해커가 전체 데이터를 탈취할 위험이 있다.


PreparedStatement 변수처리한 SQL문을 Parsing(SQL문이 맞는지 검사)한다.

그리고, 메모리에 저장한다. 캐싱에 PreparedStatement에서 검사했던 저장값이 메모리에 캐싱되어 있는 것이다.

(매우 효율적이라는 뜻 : 문법체크 1번당 1초시, 100번 실행시 1초 소모, 99초 절약)

 

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

public class Main_DBPractice2 {

	static {
		// 반드시 ojdbc14.jar 드라이버 초기화 해야한다. static으로 가장 먼저 실행
		try {
			Class.forName("oracle.jdbc.OracleDriver");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws SQLException {

		// 1. Connection 얻어오기
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String user = "test";
		String pwd = "test";
		// 커넥션에 변수로 url과 id,pwd를 넣어준다.
		Connection conn = DriverManager.getConnection(url, user, pwd);


		// 3. ResultSet 조회하기 : 조회결과를 관리하는 객체
		// 가져온 데이터 반목문 next()를 통해서 조회해주기
		// rs.next()를 통해 다음 결과가 데이터 영역인지 확인해준다.
		
		int deptno1 = 20;
		String sql = "select * from sawon where deptno = ?";
		PreparedStatement pstmt = conn.prepareStatement(sql);
		
		pstmt.setInt(1, deptno1);
		ResultSet rs = pstmt.executeQuery();
		
		
		while(rs.next()) {
			int sabun = rs.getInt("sabun");
			String saname = rs.getString("saname");
			String sasex = rs.getString("sasex");
			int deptno = rs.getInt("deptno");
			String sahire = rs.getString("sahire").substring(0,10);
			System.out.printf("%d -- %s -- %s -- %d -- %s \n",sabun,saname,sasex,deptno,sahire);
		}


		// 역순으로 닫아주기 (connection은 무한 생성이 아니므로, 닫아주어야 한다)
		rs.close();
		pstmt.close();
		conn.close();

	}
}

 

 

반응형