지난 번을 마지막으로 DB의 대략적인 내용을 파악할 수 있었다.
지금부터는 프로그래밍과 DB의 연동에 관해 공부한다.
우선 JAVA와 DB의 연동부터!!
먼저 DB연동 전 간단한 환경 설정부터 해주자.
DB 연동
다음 경로로 들어가서 ojdbc5.jar를 복사해준다.
(C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib)
jdbc는 자바와 DB를 연결해주는 클래스들의 모임이다.
쉽게 말해 자바에서 DB를 연결해줄 수 있도록 하는 확장팩이다.
다음 경로로 들어가 붙여넣기 해준다.
(C:\Program Files\Java\jre1.8.0_191\lib\ext)
이제 이클립스를 실행하여 DB 연동을 시작해본다.
우선 테스트부터 해본다.
import java.sql.*; // -> 앞서 말한 확장판을 쓴다는 선언문
public class ConnectionTest {
public static void main(String[] args) {
Connection conn = null; // -> 연결을 해주는 객체를 생성, 일단 초기값은 null로
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
// 앞서말한 JDBC 접속을 위한 인터페이스 역할(드라이버 생성)
conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:XE", "scott", "tiger");
//try 문은 예외처리를 위한 문구이다.
//try문에는 예외 발생 발생 가능성 범위를 입력해주며 그 뒤에 catch에 예외처리를 입력해주는 형식이다.
//앞서 만든 연결 객체 conn에 값을 대입해 연결을 시작한다.
//이때 DB는 oracle, type은 thin, IP는 127.0.0.1(자신의 IP를 뜻한다.), 연결 포트는 1521번
//뒤에 scott, tiger에 연결할 테이블이 있는 계정 주소를 입력해주면 된다.
System.out.println("데이터 베이스 연결에 성공했습니다");
conn.close();
System.out.println("데이터 베이스 연결 해제 성공했습니다.");
//연결 되었으면 "성공했습니다와 해제 성공하였습니다"를 출력
}catch(ClassNotFoundException e) {//jdbc를 제대로 찾지 못하였을 경우
System.out.println("JDBC Driver load fail");//jdbc driver load fail을 출력
}catch(SQLException e) {//그 외에 다른 이유로 연결에 실패하였을 경우에는
System.out.println("Connection Fali");//connection fail을 실행시켜준다.
e.printStackTrace();//에러 추적 문(사실 잘 모르겠습니다.)
}finally {//finally문은 무조건 한번은 실행시켜주는 구문이다.
try {
if(conn != null) conn.close();
//혹시 연결이 안되었을 때를 대비해 다음과 같이 실행하여준다.
} catch (SQLException e) {}
}
}
}
다음과 같은 코드를 사용하여 DB 연동이 되었는지 확인이 가능하다.
STMT
STMT(statement)는 보통 select문과 사용된다.
따로 변하는 값을 지정하지 않을 경우 사용한다. ex)select * from emp;
STMT와 다른 명령어로는 PSTMT가 있는데 구체적인 차이점은 PSTMT와 비교하면 쉽게 알 수 있다.
STMT와 PSTMT의 차이는 쿼리문에 차이가 있다. 구체적인 차이는 직접 실습을 통해 비교해보자.
import java.sql.*;
public class StmtTest {
public static void main(String[] args) {
Connection conn=null;
Statement stmt=null; //statement 객체를 생성한다.
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:XE","hr","hr");
stmt = conn.createStatement(); //연결객체와 statement 객체 결합
ResultSet rs = stmt.executeQuery("select * from employees");
//결과를 저장하는 객체인 rs 객체를 생성한다.
//stmt.executeQuery는 괄호 안에 있는 쿼리문을 실행하라는 뜻.
//실행한 결과를 rs 객체에 넣는다.
System.out.println("NAME" + "\t\t\t" + "SAL");//장식용
System.out.println("===================================");
ㅍ //장식용
while(rs.next()) {
//rs 객체는 select * from employes의 결과 레코드를 하나씩 저장한다.
//rs.next()는 다음 레코드를 rs에 저장한다는 뜻이다.
//while(rs.next)는 다음 결과가 null, 즉 존재하지 않을때까지 실행하는 반복문이다.
String fName = rs.getString("first_name");
//rs.getString("컬럼명")은 rs결과중 컬럼명을 반환한다.
//즉 위의 결과는 select * from employees 중 컬럼명이 first_name을 반환
String lName = rs.getString("last_name");
int sal = rs.getInt("salary");
//다음과 같이 getInt로 Int형 반환도 가능하다.
System.out.println(fName + lName + "\t\t" + sal );//결과 출력
}
rs.close();
stmt.close();
conn.close();//모든 객체를 종료시킨다.
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
if(stmt != null) stmt.close();
if(conn != null) conn.close();
} catch(SQLException e) {}
}
}
}
다음과 같은 결과를 확인 가능하다.(약간 칸이 안맞는데 조절을 실패하였다.)
이처럼 stmt는 주로 select 문으로 전체를 뽑아올 때 사용하며 뽑아온 데이터를 if문 혹은 스위치문을 사용하여 처리하기도 한다.
}
while(rs.next()) {
String fName = rs.getString("first_name");
String lName = rs.getString("last_name");
int sal = rs.getInt("salary");
if(sal >= 15000) //연봉이 15000 이상인 사람만 출력하라는 조건
System.out.println(fName + lName + "\t\t" + sal );
}
위와 같이 if문을 출력하면 다음과 같은 결과를 얻을 수 있다.
PSTMT
PSTMT(PreparedStatement)는 DB 캐시 영역에 저장되어 컴파일 되어있다. -> STMT보다 빠르다.
PSTMT의 가장 큰 특징은 인수 값 대신에 ?를 사용한다는 것이다. 따라서 보통 조건문이나 select 외에 DML과 같이 사용된다.
예를 들어 where 문을 사용할 때 조건을 지정해주는 것이나 insert, update문을 사용할 때 변경되는/삽입되는 데이터 값을 지정할 때 사용된다.
바로 실습으로 넘어가서 확인해보자.
import java.sql.*;
public class PstmtTest {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null; //PrepardeStatement 객체를 생성 후 초기화
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:xe","hr","hr");
String sql = "insert into departments(department_id, department_name, manager_id, location_id) values(?,?,?,?)";
//insert 문을 사용해서 departments 테이블에 레코드를 삽입하는 명령문이다..
//뒤에 value를 (?,?,?,?)로 해준 것을 확인가능하다.
//????는 변하는 데이터 값이며 사용자가 임의로 지정이 가능하다.
//뒤에 나오는 setInt, setString을 사용하여 ?에 원하는 값을 삽입할 수 있다.
pstmt = conn.prepareStatement(sql); //앞선 쿼리를 연결해준다.
pstmt.setInt(1, 280); //1번 물음표에 정수형 280을 대입하라는 뜻
pstmt.setString(2,"IT infra");//2번 물음표에 문자열 IT infra를 대입하라는 뜻
pstmt.setInt(3, 100);//3번 물음표에 정수형 100을 대입하라는 뜻
pstmt.setInt(4, 1700);//4번 물음표에 정수형 1700을 대입하라는 뜻
int cnt = pstmt.executeUpdate();
//대입한 명령어로 실행하라는 뜻이다
//이때 반환 값은 정수이며, 레코드 삽입한 갯수를 반환한다.
System.out.println("레코드" + cnt + "개 생성되었습니다.");
pstmt.close();
conn.close();
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
} catch(SQLException e) {}
}
}
}
다음과 같은 결과를 확인할 수 있다.
레코드 생성확인
실제로 IT infra가 삽입된 것을 확인할 수있다.
update문과 where문은 다음과 같이 사용가능하다.
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:xe","hr","hr");
String sql = "update departments set department_name = ? where department_id = ?"; //department_name을 바꾸기 위한 ? 와 조건을 위한 ?를 사용
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "IT infra engineer");
//department_name은 engineer로 교체
pstmt.setInt(2,280);
//이때 조건은 department_id가 280인 부서만
int cnt = pstmt.executeUpdate();
System.out.println("레코드" + cnt + "개 변경되었습니다.");
pstmt.close();
conn.close();
}
설정이 바뀐 것을 확인가능하다!!!