記錄

JAVA) JDBC 본문

Computer language/JAVA

JAVA) JDBC

surhommejk 2018. 3. 6. 12:55

기존 포스팅에서 JDBC만 따로 빼서 재 업로드






forName


public static Class<?> forName(String name,

               boolean initialize,

               ClassLoader loader)

                        throws ClassNotFoundException


Returns the Class object associated with the class or interface with the given string name, using the given class loader. Given the fully qualified name for a class or interface (in the same format returned by getName) this method attempts to locate, load, and link the class or interface. The specified class loader is used to load the class or interface. If the parameter loader is null, the class is loaded through the bootstrap class loader. The class is initialized only if the initialize parameter is true and if it has not been initialized earlier.

If name denotes a primitive type or void, an attempt will be made to locate a user-defined class in the unnamed package whose name is name. Therefore, this method cannot be used to obtain any of the Class objects representing primitive types or void.


If name denotes an array class, the component type of the array class is loaded but not initialized.


For example, in an instance method the expression:


Class.forName("Foo")

is equivalent to:

Class.forName("Foo", true, this.getClass().getClassLoader())

Note that this method throws errors related to loading, linking or initializing as specified in Sections 12.2, 12.3 and 12.4 of The Java Language Specification. Note that this method does not check whether the requested class is accessible to its caller.

If the loader is null, and a security manager is present, and the caller's class loader is not null, then this method calls the security manager's checkPermission method with a RuntimePermission("getClassLoader") permission to ensure it's ok to access the bootstrap class loader.



java.sql

Interface Connection


All Superinterfaces:

AutoCloseable, Wrapper


public interface Connection

extends Wrapper, AutoCloseable

A connection (session) with a specific database. SQL statements are executed and results are returned within the context of a connection.


A Connection object's database is able to provide information describing its tables, its supported SQL grammar, its stored procedures, the capabilities of this connection, and so on. This information is obtained with the getMetaData method.



java.beans

Class Statement


java.lang.Object

java.beans.Statement

Direct Known Subclasses:

Expression


public class Statement

extends Object

A Statement object represents a primitive statement in which a single method is applied to a target and a set of arguments - as in "a.setFoo(b)". Note that where this example uses names to denote the target and its argument, a statement object does not require a name space and is constructed with the values themselves. The statement object associates the named method with its environment as a simple set of values: the target and an array of argument values.



java.sql

Interface ResultSet


public interface ResultSet

extends Wrapper, AutoCloseable

A table of data representing a database result set, which is usually generated by executing a statement that queries the database.

A ResultSet object maintains a cursor pointing to its current row of data. Initially the cursor is positioned before the first row. The next method moves the cursor to the next row, and because it returns false when there are no more rows in the ResultSet object, it can be used in a while loop to iterate through the result set.


A default ResultSet object is not updatable and has a cursor that moves forward only. Thus, you can iterate through it only once and only from the first row to the last row. It is possible to produce ResultSet objects that are scrollable and/or updatable. The following code fragment, in which con is a valid Connection object, illustrates how to make a result set that is scrollable and insensitive to updates by others, and that is updatable. See ResultSet fields for other options.




<%@ page import="java.sql.*"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ page import="java.sql.*"%>

    <%!
    Connection connection; //DB에 연결하기 위한 인터페이스
    Statement statement; //DB에서 sql문을 실행하기 위한 메소드를 가진 인터페이스
    ResultSet resultSet; //sql문의 결과를 저장하게 되는 인터페이스

    String driver = "oracle.jdbc.driver.OracleDriver";
    String url = "jdbc:oracle:thin:@localhost:1521:xe";
    String uid = "scott";
    String upw = "tiger";
    String query = "select*from member";
    %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>
<body>

    <%
        try {

            Class.forName(driver);
            // 문자열로 주어진 클래스나 인터페이스 이름을 객체로 리턴하는 forName();

            connection = DriverManager.getConnection(url, uid, upw);
            // DriverManager는 바로 위 forName()으로 생성되었긴하나
            // DriverManager 클래스의 모든 메소드는 static이다.
            // connection 인터페이스를 DriverManager의 getConnection()을 이용해 만든다

            statement = connection.createStatement();
            //statement가 가진 executeQuery()와 executeUpdate()를 사용하기 위해
            //connection.createStatement()를 이용하여 Statment 인터페이스 객체 생성

            resultSet = statement.executeQuery(query);
            // 커서를 가지고 있는 ResultSet의 객체에 sql 명령문 결과를 넣는 과정

            while (resultSet.next()) {
                String id = resultSet.getString("id");
                String pw = resultSet.getString("pw");
                String name = resultSet.getString("name");
                String phone = resultSet.getString("phone");

                out.print("아이디: " + id + "비밀번호: " + pw + "이름: " + name +
"전화번호: " + phone + "<br/>");

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (resultSet != null)
                    resultSet.close();
                if (statement != null)
                    statement.close();
                if (connection != null)
                    connection.close();

            } catch (Exception e2) {
                e2.printStackTrace();
            }

        }
    %>

</body>
</html>







가장 중요한 프로세스를 다시 정리한다



1) class loader를 이용해서 주어진 string형식의 class name을 통해 class object를 return하는 Class.forName() 메소드를 이용해서 Class.forName("oracle.jdbc.driver.OracleDriver"); 라고 입력함으로써 메모리에 OracleDriver를 얹는다


2) OracleDriver가 메모리에 올라갔고 이를 통해 DriverManager.getConnection(url, id, pw)를 사용하여 database와의 연결을 담당하는 인터페이스인 Connection 객체를 만든다. SQL문의 명령은 Connection 인터페이스를 통해서 전달되고 결과값 역시 Connection 인터페이스를 통해 받게 된다. 


3) SQL문 실행을 위한 executeQuery()와 executeUpdate()를 갖고 있는 인터페이스인 Statement 객체를 2번에서 생성한 Connection 객체의 .createStatement()를 통해 생성한다


4) 생성된 Statement 객체의 두 메소드(executeQuery(), executeUpdate())를 이용하여 SQL문을 명령하고 이 결과 값을 ResultSet 인터페이스에 초기화 한다. ResultSet은 database의 결과값을 담는 table of data로서 커서의 개념을 갖고 있다. 처음 커서의 위치는 BOF이고 끝의 위치는 EOF라고 한다


5) ResultSet 인터페이스의 .next()를 이용해서 true or false를 반환해 while 문을 돌려서 모든 데이터가 돌아가도록 하고 .getString("~~")을 이용해서 ~~에 database에서 사용한 속성명을 넣어서 값을 가져온다.


6) 역순으로 Connection, Statement, ResultSet을 닫아준다 



cf. ResultSet의 next 구동 원리


next

boolean next()

throws SQLException


Moves the cursor froward one row from its current position. A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.

When a call to the next method returns false, the cursor is positioned after the last row. Any invocation of a ResultSet method which requires a current row will result in a SQLException being thrown. If the result set type is TYPE_FORWARD_ONLY, it is vendor specified whether their JDBC driver implementation will return false or throw an SQLException on a subsequent call to next.


If an input stream is open for the current row, a call to the method next will implicitly close it. A ResultSet object's warning chain is cleared when a new row is read.


Returns:

true if the new current row is valid; false if there are no more rows

Throws:

SQLException - if a database access error occurs or this method is called on a closed result set


=> 다음 row가 있으면 true를 반환하고 다음 row가 없으면 false를 반환한다. 다음 row에 이동을 무작정 먼저 이동하고 나서 row가 존재하면 true를 반환한다. 이런 방식으로 쿼리 검색으로 나온 모든 데이터의 row를 next를 이용해 순차적으로 돌게 된다.


구체적으로는 처음에는 BOF에 있다가(BOF는 말 그대로 before the first라서 無의 공간이다) 첫번째 row로 이동하고 두번째 실행에도 마찬가지로 이동 후 current row가 존재하면 true 반환 하면서 데이터를 읽어간다. 커서가 이동하다가 더 이상 row가 존재하지 않으면(현재 row가 쿼리 실행 결과의 마지막 row에서 이동해버려서 無의 상태가 되었을 때에) false를 반환하면서 함수가 종료된다. 정리를 하자면 n번째 실행때 커서의 위치는 n에 있고 n+1의 row가 없으면(현재 row 가 null 이면) false반환인 것이다.


커서가 row로 이동을 하면 ResultSet가 위치한 row 에서 .get~() 을 통해 데이터를 빼오면 되는데 .get~()의 파라미터에 컬럼명을 넣는 방식으로 컬럼을 특정해서 데이터를 뽑아온다. 명심할 것은 커서가 row 단위로 이동하기 때문에 언제든지 '현재'위치는 row라는 것이다.


또 주의할 것은 .get~() 에서 파라미터에는 컬럼 인덱스를 넣을 수 있다는 사실이다. 컬럼 인덱스를 정한 적도 없는데 인덱스가 왠 말? 이라고 할 수 있지만 쿼리문에 따라 생긴 컬럼의 순서별로 컬럼 인덱스가 1, 2, ... 가 되는 것이다.

'Computer language > JAVA' 카테고리의 다른 글

JAVA) 네트워크(채팅 예제 구현)  (0) 2018.02.21
JAVA) HashMap에서의 순서  (0) 2018.02.21
JAVA) HashMap의 value들을 ArrayList에 넣기  (0) 2018.02.21
JAVA) Thread  (0) 2018.02.20
JAVA) 직렬화  (0) 2018.02.20
Comments