610 likes | 1k Views
JDBC : 자바 데이터베이스. JDBC API?. JDBC 자바 언어로 다양한 종류의 관계형 데이터 베이스를 연결하고 검색할 수 있도록 해주는 자바 표준 SQL 인터페이스 API 자바의 클래스와 인터페이스로 구성. JDBC 와 ODBC 비교. ODBC MS 에서 개발 배포한 C API 불안정 void * 형 포인터 JDBC 순수한 자바 API 안정적임 자바 언어가 갖는 특성 ( 보안 , 견고성 ) 포인터 없음 어떠한 운영체제에도 가능 어떠한 종류의 관계형 데이타베이스에 접근 가능
E N D
JDBC API? • JDBC • 자바 언어로 다양한 종류의 관계형 데이터 베이스를 연결하고 검색할 수 있도록 해주는 자바 표준 SQL 인터페이스 API • 자바의 클래스와 인터페이스로 구성
JDBC와 ODBC비교 • ODBC • MS에서 개발 배포한 C API • 불안정 • void *형 포인터 • JDBC • 순수한 자바 API • 안정적임 • 자바 언어가 갖는 특성(보안, 견고성) • 포인터 없음 • 어떠한 운영체제에도 가능 • 어떠한 종류의 관계형 데이타베이스에 접근 가능 • 애플릿을 통하여 서버의 다양한 데이터 베이스에 접근 가능
JDBC를 사용하기위한 순서 • JDBC API 사용 순서 • 드라이버 적재 • 데이터 베이스 연결 • SQL문 생성 • 결과 값 처리
Application JDBC API Driver Manager JDBC Driver ORACLE Driver SYBACE Driver JDBC-ODBC Driver ODBC ORACLE SYBASE
JDBC driver의 종류(1) • JDBC-ODBC 브리지 드라이버 • JDBC-ODBC 브리지는 JDBC가 ODBC Driver에 접근하는 통로를 제공 • 단점 • JDBC API로 작성된 프로그램이 동작하는 컴퓨터에 반드시 ODBC 드라이버가 존재해야 한다. • ODBC 드라이브를 통해서 데이터베이스에 접근하므로 속도가 느리다. • 장점 • DBMS에서 ODBC 드라이버를 제공하고 있으면 DBMS를 위한 다른 JDBC 드라이버가 필요 없다.
JDBC-ODBC 브리지 드라이버 클라이언트 컴퓨터 서버 DBMS 자바 프로그램 (java) JDBC-ODBC Library (Native Code) ODBC 드라이버 (Native Code) JDBC- ODBC브리지 (java) D/B
JDBC driver의 종류(2) • 데이터베이스 API(A native-API partly-Java) 드라이버 • JDBC API 호출을 특정 데이터베이스의 클라이언트 호출 API로 바꿔 주는 드라이버 • JDBC API ----> D/B API 드라이버---> Oracle • JDBC프로그램이 동작하는 클라이언트쪽에 반드시 특정 데이터 베이스의 클라이언트 호출 API가 필요 • Oracle의 OCI(Oracle Call Interface) 드라이버 • C/C++, liboci73jdbc.so(Version 7.3), libocijdbc8.so(8,x버전)
A native-API partly-Java 클라이언트 컴퓨터 서버 DBMS native 라이브러리 JDBC API D/B
JDBC driver의 종류(3) • 네트워크 프로토콜(A net-protocol all-java) 드라이버 • 클라이언트의 JDBC API 호출을 특정 데이터베이스의 프로토콜과 전혀 상관없는 독자적인 방식의 프로토콜로 바꾸어 서버로 전송한다. • 서버에서는 미들웨어가 있어서 그 프로토콜을 특정 데이터베이스의 API로 바꾸어서 처리한다. • Java Applet프로그램이나 servlet프로그램을 위해 적당 • 일반적으로 현재 이 방식의 드라이버가 인트라넷 환경에서 많이 적용되고 있는 스타일이다.
JDBC driver의 종류(3) • 순서 • JDBC API를 사용한 애플릿 로드(JDBC-Net Driver도 로드) • 애플릿이 JDBC API를 호출 • JDBC-Net Driver가 독자적인 프로토콜로 변환 • 서버의 Middleware가 특정 데이터 베이스 API로 변환 • 특정 데이터 베이스에 접근 • 값을 얻어서 클라이언트 JDBC-Net 드라이버에게 전송 • 자바 애플릿은 값을 얻어서 처리
A net-protocol all-java 클라이언트 컴퓨터 서버 DBMS 표준네트워크 프로토콜 드라이버 미들 웨어 JDBC API D/B
JDBC driver의 종류(4) • 데이터베이스 프로토콜(A native-protocol all-java) 드라이버 • JDBC API 호출을 서버의 특정 데이터베이스에 맞는 프로토콜로 변환시켜 서버로 전송하는 드라이버이다 • 두 번째 형식과 비슷하지만 데이터베이스의 클라이언트 API로 변환시키는 것이 아니라 직접 서버의 데이터베이스로 요청을 한다는 것이 다르다 • 이 형식의 드라이버는 데이터 베이스를 생산하는 회사가 직접 제공
JDBC driver의 종류(4) • 순서 • JDBC API를 사용한 애플릿을 다운(데이터 베이스 프로토콜 드라이버도 download) • JDBC API호출 • 데이터 베이스 프로토콜 드라이버가 그것을 특정 데이터 베이스 프로토콜로 전환해 데이터 베이스 서버에 전송 • 나머지 과정 동일 • 인터넷에 가장 바람직한 드라이버 • 세 번째와 네 번째 형태의 드라이버 • 클라이언트에게 특별한 드라이버 설치가 불필요
A native-protocol all-java 서버 DBMS 클라이언트 컴퓨터 독자 네트워크 프로토콜 JDBC API D/B
각종 DBMS를 위한 JDBC Driver • Currently available drivers • http://java.sun.com/products/jdbc/drivers.html • 오라클용 JDBC 드라이버 • http://www.oracle.com/java/jdbc/index.html • mSQL • DBMS(14일간 무료) • http://www.Hughes.com.au/ • JDBC Driver • http://www.imaginary.com/java/
각종 DBMS를 위한 JDBC Driver • POSTGRES • DBMS(무료) • http://www.postgresql.org/ • JDBC 드라이버 • http://www.postgresql.org • Oracle JDBC Driver • http://technet.oracle.co.kr/isp/plsql/consumer_chk/ • http://www.oracle-korea.com • http://technet.oracle.com/software/
JDBC 데이터베이스 접근 모델(1) • 2 -tier Model • 자바 애플릿이나 어플리케이션이 직접 데이타베이스에 접근 • JDBC가 접근될 특정 데이터 베이스와 통신 가능 • Security, Load Balancing, 확장성 때문에 3 Tier를 선호 Java Application Client machine JDBC DBMS-proprietary protocol DBMS Database server
JDBC 데이터베이스 접근 모델(2) • 3 Tier 모델 • 클라이언트는 database에 관련된 일을 처리하기 위해 MiddleWare에 있는 원격 객체를 호출 • 실질적으로 MiddleWare가 Database로 연결설정과 SQL문을 호출한다. Java applet or HTML browser Client machine(GUI) HTTP, RMI, or CORBA calls 미들웨어 Server machine(business logic) JDBC DBMS-proprietary protocol DBMS DBMS Database server
JDBC 프로그래밍 절차 • JDBC드라이버를 등록 • Driver Manager의 getConnection()를 이용해서 Connection객체를 얻는다. • Connection객체의 createStatement()를 통해 Statement객체를 얻는다. • Statement객체의 executeQuery()나 executeUpdate()를 이용해 SQL을 데이터 베이스 서버에 보낸다. • ResultSet객체의 getXXX()를 통해 SQL문장의 실행 결과를 얻는다. • Statement객체와 Connection객체의 Close를 호출해서 연결을 닫는다.
JDBC에서 중요한 인터페이스 들간의 관계 Driver Manager Connection Connection Connection Statement Statement Statement Statement Result Result Result
JDBC API로 프로그래밍하는 법(1) • JDBC 드라이버를 선택하고 메모리에 올린다. • Class 클래스를 사용 ex) Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”); • 특정 데이터베이스와 연결한다. • Connection, DriverManager 인터페이스 사용 • Connection con = DriverManager.getConnection(“jdbc:odbc:testDB”, “login”, “password”); • SQL 문장을 연결된 데이터베이스에게 보낸다. • Statement, ResultSet 인터페이스를 사용 • Statement stmt = con.createStatement(); Result rs = stmt.executeQuery(“select * from testTable”);
JDBC API로 프로그래밍하는 법(2) • SQL 문장을 통해 얻은 값을 처리한다. • ResultSet의 인스턴트 reference를 이용 • while(rs.next()) • { int x = rs.getInt(1); String y = rs.getString(2); float z = getFloat(3); System.out.println(“x = “ + x + “y = “ + y + “z = “ + z); }
JDBC API의 단계별 사용법 • JDBC 드라이브를 메모리에 적재 • DBC 드라이브와 해당 데이터베이스를 연결 • 연결된 데이터베이스에게 SQL 질의 • ResultSet 인터페이스의 사용
JDBC 드라이브를 메모리 적재(1) • 명령어 상에서 • jdbc.drivers 프로퍼티를 사용하는 방법(prompt상) • java -Djdbc.drivers=postgress95 : msspl mydb • java.lang.System의 속성인 jdbc.drivers를 지정 • 특정 파일 안에 드라이버 이름을 적어 주는 방식이다. • JDK 의 하위디렉토리에 properties라는 파일이 있는데, 여기에 JDBC 드라이버 이름을 적어 주면 된다. • jdbc.drivers=JDBC 드라이버 이름 1;JDBC 드라이버 이름 2; …….
JDBC 드라이브를 메모리 적재(2) • 프로그램 내에서 지정 • Class 클래스의 forName 메소드를 이용 • Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”); • DriverManager의 registerDriver를 이용 • Driver driver = new sun.jdbc.odbc.JdbcOdbcDriver(); • java.sql.DriverManager.registerDriver(driver);
Driver Manager와 Driver와의 관계 Program jdbc Url---->B Driver Manager Jdbc url에 맞는 driver를 찾음 jdbc:B Driver jdbc:C Driver jdbc:A Driver Connection to myDB myDB
해당 데이터베이스를 연결 • DriverManager • 현재 사용 가능한 JDBC 드라이버를 파악 • JDBC 드라이버와 그 데이터베이스와의 연결 담당 • JDBC 사용 기록 메시지의 출력 • 로그인 시간 제한 • 연결 방법 • public static synchronized Connection getConnection(String url, String user, String Password) throws SQLException
JDBC URL(1) • 특정 데이터베이스와 연결을 위한 데이터베이스의 위치를 가리키는 URL • 표준 형식 • jdbc:<subprotocol>:<subname> • jdbc : JDBC URL임을 나타내는 단어 • subprotocol : • 연결하고자 하는 데이터베이스의 드라이버 이름 • 데이터 베이스를 연결할 때 사용하는 메카니즘
JDBC URL(2) • subname : • 데이터베이스의 이름과 위치를 정확하게 기술 • subprotocol에 따라 변경 • 드라이버를 작성하는 곳의 문법에 따라 subname을 가질 수 있다 • Postgress에 접근할때 사용하는 URL • ex) jdbc:postgress95://www.kyusik.net:8000/Sample • ODBC를 접근할 때 사용하는 JDBC URL • jdbc:odbc:<data-source-name>[;<sttribute-name>=<attribute-value>]*
SQL Query(1) • 다음 인터페이스 중에서 한 개의 객체를 생성 • Statement • PreparedStatement • CallableStatement
Statement 인터페이스 • Statement객체 생성예제 • Connection con = DriverManager.getConnection() • Statement st = con.createStatement() • 용도 • 간단한 SQL을 전송할 때 사용 • createStatement의 prototype • public abstract Statement createStatement() throws SQLException
PreparedStatement 인터페이스 • 예제 • Connection con = Drivermanger.getconnection; • PreparedStatement st = con.prepareStatement(); • 용도 • SQL 문장에 한 개 이상의 “IN 파라미터”가 전달되어 실행되는 경우에 사용 • 미리 컴파일한 SQL문장을 사용할 때
CallableStatement 인터페이스 • 예제 • Connection con = Drivermanger.getconnection; • CallableStatement st = con.prepareCall(); • 용도 • 여러 개의 SQL 문장을 저장하여 그것을 한 번에 실행하고자 할 때 사용 • 주로 Stored procedure를 호출할 때 사용
Statement객체를 통한 질의 • Statement 객체로 SQL 질의를 하는 3가지 함수 • executeQuery(String sql) • executeUpdate() • execute()
executeQuery함수 • 예제 • Result rs = stmt.executeQuery(“SELECT a, b, c FROM testTable); • 용도 • SQL 문장을 실행한 후의 결과값이 한 개일 때 사용 • prototype • public abstract ResultSet executeQuery(String sql) throws SQLException
executeUpdate함수 • 예제 • int state = stmt.executeUpdate(“DELETE customer WHERE p > 10”); • 용도 • INSERT, UPDATE, DELETE 문장이나 CREATE TABLE, DROP TABLE과 같은 SQL DDL(Data Definition Language) 문장들을 실행 시 • 즉 실행 결과값이 필요 없는 SQL 문장을 사용 • Insert, Update, delete의 경우 SQL문장의 영향을 받은 열(rows)의 수 반환 • DDL의 경우 변환 된 행이 없기 때문에 0을 리턴
Execute함수(1) • 사용 예 • Connection con = DriverManager.getConnection() • Statement st = con.createStatement() • st.execute(sqlStatementWithUnknownResults); • Commit • Auto-commit인 경우 Statement는 SQL을 실행하고 리턴 값을 받는 동시에 자동으로 Commit이나 Rollback
execute를 통해 반환 값을 얻는 과정 • ResultSet과 카운터 중에서 무엇이 return 될지 모르는 경우 • Return값이 True • ResultSet객체 반환 • 다음에 getResultset함수 호출 • 2개의 결과 값을 리턴 하는 경우 • execute()--->getResultset()----->getMoreResults()를 호출 • getResultset이 null을 리턴 • 결과가 갱신횟수 이거나 더 이상 결과가 없다는 것 • getUpdateCount를 호출해 어떤 경우인지 조사 • -1은 갱신 횟수가 더 이상 없다는 것
execute를 통해 반환 값을 얻는 과정 • Return값이 False • 갱신횟수를 반환 • 다음에 getUpdateCount를 호출 • 두개의 카운터를 리턴 할 경우 • getUpdateCount()---->getMoreResults()---->getUpdateCount()--->
Execute함수(2) • 용도 • SQL 문장이 한 개 이상의 ResultSet 객체 반환 • 하나 이상의 갱신횟수를 갖는 Sql문 • ResultSet과 갱신횟수의 조합을 리턴 • 변화된 행의 개수(Update Count)등을 반환할 가능성이 있을 경우 • 저장 프로시져(Stored Procedure)를 실행 • 프로그래머가 컴파일 시에 알 수 없는 SQL 문장을 실행할 때 사용
PreparedStatement객체를 통한 질의 • 용도 • 이미 컴파일된 SQL 문장 • 한 개 이상의 IN 파라미터를 가진 경우 • 보통 “?”문자를 IN 파라미터 자리에 쓴다. • IN 파라미터에 들어갈 값은 setXXX 메소드를 사용하여 할당 // PreparedStatement 객체를 사용하여 SQL 질의를 한 예 PreparedStatement pstmt = con.preparedStatement(“UPDATE testTable SET m = ? WHERE x = ?”); psmt.setLong(1, 12345); psmt.setString(2, “Hello”);
setString()나 setBytes()는 무제한의 길이를 보낼 수 있지만 큰 데이터는 작은 데이터로 쪼개어 보냄 • 해결 방법 • 자바 입력 스트림을 형성
입력 스트립을 위한 3가지 메소드 • 바이너리 스트림 • setBinaryStream() ---->d/b에 대용량 데이터 output • getBinaryStream() ----->d/b에 대용량 데이터 input • ASCII문자를 포함한 스트림 • setAsciiStream() • getAsciiStream() • 유니코드 문자를 포함한 스트림 • setUnicodeStream()
바이너리 스트림을 통한 파일의 내용을 데이터 베이스에 보내는 예제 java.io.File file = new java.io.File(“/tmp/data”); int fileLength = file.length(); java.io.InputStream fin = new java.io.FileInputStream(file) java.sql.PreparedStatement pstmt = new con.prepareStatement (“Update Table5 SET stuff= ? WHERE index = 4”); pstmt.setBinaryStream(1,fin,fileLength); pstmt.executeUpdate();
긴 ASCII 문자열을 읽어 들이는 소스 Connection 및 Statement의 생성을 가정 try { ResultSet rs = stmt.executeQuery( “select Title, sender, Message from Messages where message_id = 9”); if(rs.next()) { out.println(“<h1>” + rs.getString(“title”) + “</h1>”); out.println(“<b>From:</b>” + rs.getString(“sender”) + “<br>”); BufferedReader b = new BufferedReader( new InputStreamReader(rs.getAsciiStream(“message”))); while(b.ready()) { out.println(b.readLine()); } } }catch(SQLException e) { //report 코드 들어올것 }
CallableStatement객체를 통한 질의 • 용도 • stored SQL procedure를 호출 • 사용 예제 • Connection con = DriverManager.getConnection(); • CallableStatement cstmt = con.prepareCall(“{call getTestData(?,?)}”); • IN파라메타는 setXXX()를 통하여 함 • 저장된 프로시저가 OUT 파라메타를 리턴 한다면 • CallableStatement가 실행되기전에 registerOutParameter()를 사용해 사전에 등록 • CallableStatement는 INOUT 파라메타를 사용 가능
Stored Procedures • 대부분의 RDBMS 시스템은 일종의 내부적인 프로그래밍 언어를 포함 • 예: 오라클의 PL/SQL • 데이터베이스 개발자가 절차적인 애플리케이션 코드를 데이터 베이스 내부에 저장할 수 있게 함 • 다른 애플리케이션에서 이들을 호출 • 장점 • RDBMS에서 미리 전처리 됨으로써, 동적인 SQL보다 빠르다 • RDBMS안에서 수행됨으로 네트워크 트래픽 없이 다중 질의어와 갱신 작업이 가능
Out 파라메타 예제 Connection con = DriverManager.getConnection(); CallableStatement cstmt = con.prepareCall(“ call getTestDate (?,?)}”); cstmt.registerOutputParameter(1,java.sql.Types.TINYINT); cstmt.registerOutputParameter(2, java.sql.Types.DECIMAL, 3); cstmt.executeQuery(); byte x = cstmt.getByte(1); java.math.BigDecimal n = cstmt.getBigDecimal(2,3);
ResultSet에서 값 읽어 오기 getXXX() getXXX() rs.next() getXXX() -1 커서 row colume ResultSet