JDBC
- Java에서 DB에 접근할 수 있게 해주는 Java Programming API
- java.sql 패키지 안에 존재:
https://docs.oracle.com/en/java/javase/17/docs/api/java.sql/java/sql/package-summary.html
- JDBC를 이용한 애플리케이션 제작 시 필요한 것
1) Java의 JDBC 관련 인터페이스
2) DBMS의 종류(Oracle)
3) DBMS 회사에서 제공하는 Java 애플리케이션과 DB 연결을 위한 라이브러리(ojdbc11.jar의 OracleDriver.class)
OJDBC
- 오라클에서 제공하는 오라클 DB와 자바가 연결하기 위한 라이브러리
- 라이브러리 다운로드:
https://mvnrepository.com/
JDBC 사용 객체
- DriverManager:
데이터 원본에 JDBC드라이버를 통하여 커넥션을 만드는 역할
Class.forName() 메서드를 통해 생성되며 반드시 예외처리를 해야 함
직접 객체 생성이 불가능하고 getConnection() 메서드를 사용하여 객체 생성 가능- Connection:
특정 데이터 원본과 연결된 커넥션을 나타내며 Statement객체를 생성할 때도
Connection 객체를 사용하여 createStatement() 메서드를 호출하여 생성
SQL문장을 실행시키기 전에 우선 Connection 객체가 있어야 함- Statement:
Connection 객체에 의해 프로그램에 리턴되는 객체에 의해 구현되는 일종의 메서드 집합 정의
Connection 클래스의 createStatement() 메서드를 호출하여 얻어지며
생성된 Statement 객체로 질의문장을 String 객체에 담아 인자로 전달하여
executeQuery() 메서드를 호출하여 SQL질의 수행
- PreparedStatement:
Connection객체의 preparedStatement() 메서드를 사용하여 객체 생성
SQL문장이 미리 컴파일 되고 실행 시간 동안
인수 값을 위한 공간을 확보한다는 점에서 Statement와 다름
각각의 인수에 대해 위치 홀더(?)를 사용하여 SQL문장을 정의할 수 있게 함
- ResultSet:
SELECT문을 사용한 질의 성공 시 Result Set 반환
SQL질의에 의해 생성된 테이블을 담고 있으며 커서로 특정 행에 대한 참조 조작
JDBC 코딩 흐름
JDBC 코딩 절차
- 1단계: JDBC 객체 참조 변수 선언
- Connection:
DB 연결 정보를 담은 객체(Java-DB 연결 통로)- Statement:
Connection을 이용해서 SQL을 DB에 전달하여 수행 후 결과를 반환받는 객체- ResultSet:
SELECT 수행 결과를 저장하는 객체(커서를 이용해 1행씩 접근)- Statement는 java.sql.Statement임에 주의
- 2단계: 참조 변수에 알맞은 객체 대입
- 각종 예외가 발생하니 try-catch문으로 예외 처리
- DriverManager.getConnection(): Connection을 생성하는 메서드
- createStatement(): Statement를 생성하는 메서드
- Class.forName():
DB 연결에 필요한 JDBC 드라이버를 메모리 로드
DriverManager가 Connection 생성 시 자동으로 사용- Java에서 작성되는 SQL은 마지막에 세미콜론(;)을 찍지 않음
- SQL 작성할 때 개행 시 띄어쓰기에 유의
- executeQuery(): SELECT 수행 후 ResultSet 반환
- 3단계: SQL 수행 결과로 받환받은 ResultSet을 첫번째 행부터 1행씩 접근하여 컬럼 값을 얻어와 출력
- rs.next(): 커서를 1행 이동시켜 다음 행이 있으면 True, 없으면 False 반환
- 4단계: 사용한 JDBC 객체 자원 반환
- close 구문은 객체 생성 역순으로 진행
public class JDBCExample { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // 1단계: JDBC 객체 참조 변수 선언 Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // 2단계: 참조 변수에 알맞은 객체 대입 Class.forName("oracle.jdbc.driver.OracleDriver"); String type = "jdbc:oracle:thin:@"; // Connection 생성 시 필요한 값을 변수에 대입 String ip = "localhost"; String port = ":1521"; String dbName = ":ORCL"; String user = "kh_lsj"; String pw = "oracle"; conn = DriverManager.getConnection(type+ip+port+dbName, user, pw); // Connection 생성 stmt = conn.createStatement(); // Statement 생성 System.err.print("급여 기준 입력: "); int input = sc.nextInt(); // SQL 작성 String sql = "SELECT EMP_NAME, SALARY, JOB_CODE, HIRE_DATE " +"FROM EMPLOYEE " +"WHERE SALARY >= " + input +" ORDER BY SALARY DESC"; rs = stmt.executeQuery(sql); // 3단계: SQL 수행 결과로 받환받은 ResultSet을 // 첫번째 행부터 1행씩 접근하여 컬럼 값을 얻어와 출력 while(rs.next()) { String empName = rs.getString("EMP_NAME"); int salary = rs.getInt("SALARY"); String jobCode = rs.getString("JOB_CODE"); Date hireDate = rs.getDate("HIRE_DATE"); System.out.printf("이름: %s / 급여: %d / 직급코드: %s / 입사일: %s \n", empName, salary, jobCode, hireDate.toString()); } }catch(ClassNotFoundException e) { e.printStackTrace(); }catch(SQLException e) { e.printStackTrace(); }finally { // 4단계: 사용한 JDBC 객체 자원 반환 try { if(rs != null) rs.close(); if(stmt != null) stmt.close(); if(conn != null) conn.close(); }catch (SQLException e) { e.printStackTrace(); } } } }
JDBC 코딩 시 주요 에러
- 구문에 오타가 있는 경우:
Class.forName("oracle.jdbc.driver.OracleDriver");- 아이디 또는 비밀번호 오타:
java.sql.SQLException: ORA-01017:
사용자명/비밀번호가 부적합, 로그온할 수 없습니다- DB 연결을 위한 URL (type, ip, port, dbName)에 오타:
java.sql.SQLRecoverableException: IO 오류:
The Network Adapter could not establish the connection- SQL 문법이 잘못됨:
java.sql.SQLSyntaxErrorException- SQL에 세미콜론이 포함됨:
java.sql.SQLSyntaxErrorException: ORA-00933:
SQL 명령어가 올바르게 종료되지 않았습니다- Statement를 이용해서 SQL 수행 시 SQL이 ""(빈문자열) 또는 NULL인 경우:
java.sql.SQLException: 실행할 SQL 문은 비어 있거나 널일 수 없음- rs.get자료형("컬럼명") 구문에서 "컬럼명"을 잘못 작성한 경우:
java.sql.SQLException: 부적합한 열 이름
JDBC 코딩 시 주요 명령어
- System.exit(0):
프로그램 종료- Session.loginMember.getMemberNo():
세션의 logigMember에서 MemberNo 가져오기- StringBuffer:
고정된 문자열을 저장하는 String과 달리 가변 문자열을 저장하는 타입
게시글 내용 등 긴 문자열 저장하는 목적으로 자주 사용- Connection conn = getConnection();:
커넥션 개체 conn 생성
주로 service에서 생성해서 dao로 던짐- String sql = prop.getProperty("insertBoard");:
dao에서 xml의 entry 키 값 불러와 entry 내용을 String 타입의 sql 객체에 저장- stmt = conn.createStatement();:
xml에 적은 SQL문을 실행하기 위해 생성하는 객체- pstmt = conn.prepareStatement(sql);:
xml에 적은 SQL문의 ?(place holder)에 값을 채워넣기 위해 생성하는 객체- pstmt.executeUpdate():
- DML 구문을 사용할 때 사용(INSERT, UPDATE, DELETE)
- DML 구문에 영향을 받은 행의 개수를 int 값으로 반환
- 데이터 변경에 사용
- stmt의 경우 execute의 괄호 안에 sql문이 담긴 객체를 삽입
- pstmt.executeQuery():
- SELECT문을 사용할 때 사용
- ResultSet 형태로 반환
- 데이터베이스에서 결과 집합을 가져오는데 사용
- stmt의 경우 execute의 괄호 안에 sql문이 담긴 객체를 삽입