본문 바로가기

닷컴's_열공/JSP

[09] 데이터베이스 접속 패턴, JDBC - Oracle, JSP 연동

▩ 데이터베이스 접속 패턴

1. JSP ---------------------------------------> Oracle
   . JSP에서 처리 로직 전부 구현
   . 개발이 단순하나 개발 기간 지연이 많이 발생하고 유지보수가 매우 어렵습니다.
         
             

2. JSP -----> Beans --------------------------> Oracle
   . 보여주는 로직을 JSP에서 구현
   . Beans는 처리로직으로 1번의 개발 패턴보다는 유지보수성이 많이 우수합니다.
   . 개발시 beans를 설계하여 구현한후 jsp를 구현합니다.
   . 데이터베이스 접속 시간이 많이 소요됩니다.
   . 많이 사용되는 패턴


3. JSP ------------------> Pool --------------> Oracle
   . JSP에서 처리 로직 전부 구현 그러나 데이베이스 연결 부분만 Pool 객체에서 구현합니다.
   . 개발이 단순하나 개발 기간 지연이 많이 발생하고 유지보수가 매우 어렵습니다.
   . 데이터베이스 접속은 빨리 됩니다.


4. JSP ----------------> Beans --------------> Pool -----------------> Oracle (권장)
   rank.jsp           RankDTO.java      DBConnectionMgr.java           Rank Table
                      RankMgr.java

   . 보여주는 로직을 JSP에서 구현
   . Beans는 처리로직(Business Logic)으로 유지보수성이 많이 우수합니다.
   . 개발시 beans를 설계하여 구현한후 jsp를 구현합니다.
   . 신속한 데이터베이스 접속이 이루어 집니다.  
   . 많이 사용되며 권장 패턴입니다.




▩ JDBC Driver, RDBMS의 연동

1. JDBC Driver Type
   - Type 1
     . JDBC-ODBC Bridge Plus ODBC Drive: 다양한 데이터에 접속이 가능하나 속도가 느리다.
     . ODBC의 사용 : javamssqlODBC 만들기 , [관리 도구]-[데이터 원본]-[System DSN]
     . ODBC를 사용하는 경우는 자바가 JDBC드라이버를 Vendor로 부터 지원받을 수 없는 경우에만 해당합니다.
       거의 모든 자바 드라이버가 전부 제공됨으로 사용예는 극히 적습니다.

   - Type 2
     . Native-API Partly-java Driver:C로 개발된 드라이버를 이용하여 데이터베이스 접속,
     . 데이터접속 드라이버가 클라이언트쪽에 위치해 있다.

   - Type 3
     . JDBC-Net Pure Java Driver: 순수 자바 드라이버, 데이터접속 드라이버가 서버쪽에 위치해 있다.

   - Type 4
     . Native-Protocol Pure Java Driver: 순수 자바 드라이버로 자바를 이용해서 바로 데이터베이스 서버에 접속됩니다.
     . 자바 Socket을 이용하여 DB 서버에 접속하는 네트워크 프로그램입니다.
     . thin-Oracle: 1521, jk-MSSQL:1433, MySQL Connector/J: 3306



2. 환경 설정
   - classes12.jar 파일을 복사
     . \webapps\www\WEB-INF\lib: www Application만 사용가능
     . \tomcat-5.5.20\common\lib : 모든 Application이 사용가능
     . 주의: WEB-INF\lib, common\lib 두 폴더에 같은 라이브러리가
       있으면 안됩니다.

   - Web Application Folder
     . /tomcat-5.5.20/webapps/jdbc                  : *.jsp
     . /tomcat-5.5.20/webapps/jdbc/WEB-INF          : web.xml
     . /tomcat-5.5.20/webapps/jdbc/WEB-INF/classes  : servlet, beans
     . /tomcat-5.5.20/webapps/jdbc/WEB-INF/lib      : classes12.jar

   - Eclipse
     . Project Name  : jsp_c09_jdbc
     . Library       : servlet-api.jar, classes12.jar
     . output folder : '/tomcat-5.5.20/webapps/jdbc/WEB-INF/classes' link



3. JAVA JDBC 연동 테스트

>>>>> test.jdbc.DriverTest.java

package test.jdbc;

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

public class DriverTest {
    public static void main(String args[]){
        //데이터베이스 접속 연결 정보를 가지고 있는 객체입니다.
        Connection con;
   
        try{
            //JDBC드라이버를 로딩합니다.
            Class.forName("oracle.jdbc.driver.OracleDriver");
           
            //데이터베이스에 연결을 합니다.               Oracle Server IP:Port:SID     계정명         패스워드                     
            con=DriverManager.getConnection("jdbc:oracle:thin:@172.16.6.1:1521:ora93","jsp2030_02_1","oracle");
           
            System.out.println("데이터 베이스 접속이 성공했습니다.");
        }catch(SQLException  ex){
            System.out.println("SQLException:"+ex);
        }catch(Exception ex){
            System.out.println("Exception:"+ex.toString());
        }
     }
}



4. JSP JDBC 연동 실습

   - 테이블 구조

DROP TABLE book;
DROP SEQUENCE book_booknum_seq;

-- CONSTRAINT book_num_pk PRIMARY KEY(num)
-- CONSTRAINT 제약조건 이름 PRIMARY KEY(조건을 지정할 컬럼명)
-- PRIMARY KEY: 중복된 값이 올 수 없습니다. null이 값으로
-- 올 수 없음으로 반드시 INSERT시에 값을 입력해야 합니다.
CREATE TABLE book(
   booknum    NUMBER(5)      NOT NULL, -- -99999 ~ +99999, 책 번호
   name           VARCHAR(20)  NOT NULL, -- 도서명
   author         VARCHAR(20)  NOT NULL, -- 저자
   price            NUMBER(6)     NOT NULL, -- 가격,
   CONSTRAINT book_booknum_pk PRIMARY KEY(booknum)
);

-- SEQUENCE: 고유한 일련번호를 생성합니다.
-- CREATE SEQUENCE 시쿼스 이름, 테이블명_컬럼명_seq
-- START WITH 시작값 지정
-- INCREMENT BY 증가값 지정
-- CACHE 메모리에 저장할 캐시값, 10이면 10단위로
-- sequence 테이블이 수정됩니다.

CREATE SEQUENCE book_booknum_seq
START WITH 1
INCREMENT BY 1
CACHE 10;


--추가
INSERT INTO book(booknum, name, author, price)
VALUES(book_booknum_seq.NextVal, 'JSP 개발','저자1', 25000);

INSERT INTO book(booknum, name, author, price)
VALUES(book_booknum_seq.nextval, 'EJB 개발','저자2', 25000);

INSERT INTO book(booknum, name, author, price)
VALUES(book_booknum_seq.nextval, 'CBD 개발','저자3', 27000);

SELECT booknum, name, author, price FROM book; 

COMMIT;



-------------------------------------------------------------------------------
>>>>> webapps/jdbc/jdbc_test.jsp, http://127.0.0.1:8081/jdbc/jdbc_test.jsp
-------------------------------------------------------------------------------
- 데이터베이스에 레코드 추가 후 SELECT 예제입니다.

<%@ page contentType="text/html;charset=euc-kr" %>
<%@ page import="java.sql.*, java.text.DecimalFormat" %>

<%!
public String comma(int p){
    DecimalFormat comma = new DecimalFormat("###,##0");//1,000,000
    return comma.format(p);
}

public String comma(long p){
    DecimalFormat comma = new DecimalFormat("###,##0");
    return comma.format(p);
}
%>

<%
Class.forName("oracle.jdbc.driver.OracleDriver");
  
//드라이버로딩 후 커넥션을 위한 커넥션 객체선언
Connection con = null;
  
//커넥션이 생성이 된 후 질의를 던지기 위한 객체선언
Statement stmt = null;

//SELECT 쿼리의 결과만 가져옵니다.
ResultSet rs = null;
 
int booknum=0;       //책 일련 번호
String name = "";    //책 제목
String author = "";  //저자명
int price = 0;           //가격
float dc = 0.1f;        //할인율
int sale = 0;            //판매가격
int counter = 0;     //등록된 책의 수
int ret=0;               //추가된 레코드의 수 

String url="jdbc:oracle:thin:@172.16.6.1:1521:ora93";
String user="jsp2030_02_1";
String pass="oracle";

try{
   //커넥션 생성
   con = DriverManager.getConnection(url, user, pass);
 
   //커넥션을 통해 질의를 전송하기 위한 객체(stmt)를 생성합니다.
   stmt = con.createStatement();

   // INSERT
   // -------------------------------------------------------------------------------
   String sql = "INSERT INTO book(booknum, name, author, price) ";
   sql = sql + " VALUES(book_booknum_seq.nextval, 'JAVA', '저자',25000)";

   //ret: insert한 레코드의 수
   ret = stmt.executeUpdate(sql); //record insert
   System.out.println(sql); //console에 쿼리 출력
  
   if( ret > 0) {
        System.out.println(ret + "개의 메소드가 추가되었습니다.");
   }
  
   // SELECT
   // -------------------------------------------------------------------------------
   sql = "SELECT booknum, name, author, price FROM book";
   sql = sql + " ORDER BY booknum DESC";

   //객체(stmt)를 통해서 질의를 수행할 메소드를 사용
   //질의수행 결과는 ResultSet(Record의 집합)으로 받는다.
   rs = stmt.executeQuery(sql);
%>
<html>
<head>
<title>JSP에서 데이터베이스 연동</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
</head>
<body bgcolor="#FFFFCC">

<h2>JSP 스크립틀릿에서 데이터베이스 연동 예제입니다....</h2>

<br>
<br>
<h3>도서정보</h3>
<table bordercolor="#0000ff" border="1">
<tr>
    <td><strong>책 번호</strong></td>
    <td><strong>책 이름</strong></td>
    <td><strong>저자</strong></td>
    <td><strong>가격</strong></td>
    <td><strong>할인율</strong></td>
    <td><strong>판매가격</strong></td>
</tr>
<%
    if(rs != null){  //rs 객체가 정상적으로 생성이 되어 있다면

         /*최초 레코드 포인터는 BOF 지역을 가르키고 있습니다.
         첫번째 레코드로 이동하면서 레코드 포인터를 증가합니다.
         만약 다음 레코드가 없으면 false를 리턴해 while문을
         벗어납니다.*/
         while(rs.next()){
            booknum = rs.getInt("booknum");   //booknum = rs.getInt(1);
            name   = rs.getString("name");    //name = rs.getString(2);
            author = rs.getString("author");
            price  = rs.getInt("price");
            sale   = (int)(price * (1 - dc)); //할인율이 적용된 금액
            sale   = ((int)(sale /100 + 0.5))*100;  //10의자리에서 반올림
            // 1555 --> 15.55 ---> (int)16.05 ---> 16 ---> 1600
%>
<tr>
<td>&nbsp; <%= booknum %> &nbsp;</td>
<td>&nbsp; <%= name %> &nbsp;</td>
<td>&nbsp; <%= author %> &nbsp;</td>
<td>&nbsp; <%= comma(price) %> &nbsp;</td>
<td>&nbsp; <%= dc %> &nbsp;</td>
<td>&nbsp; <font color="red"><%= comma(sale) %></font> &nbsp;</td>
<%
            counter++;
         }//end while
      }//end if
%>

</tr>
</table>
<BR>
<BR>
total records : <%= counter %>
<%
//데이터베이스 연동시 필요한 예외처리...
}catch(Exception e){
    System.out.println(e.toString());
}finally{
    if( rs != null )
        try{ rs.close(); }
        catch(SQLException e) {System.out.println(e.toString());}
    if( stmt != null )
         try { stmt.close(); }
        catch(SQLException e) {System.out.println(e.toString());}
    if( con != null )
         try{ con.close(); }
        catch(SQLException e) {System.out.println(e.toString());}
}
%>