ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 웹프로그래밍과 데이터베이스 관련내용 정리
    웹프로그래밍/기초 2018. 4. 14. 16:00

    웹 프로그래밍과 데이터베이스



    웹 프로그래밍에서 데이터베이스 사용은 필수적이다. 


    (예를 들어, 쇼핑몰 사이트의 회원정보, 주문내역 저장)


    데이터베이스 자체에는 기능이 많지 않으므로 DBMS를 이용한다.


    데이터베이스를 관리하는 시스템을 DBMS이라고 하며


    하위 개념인 RDBMS로는 오라클, MySQL, MS SQL 등이 있다.


    DBMS의 주요 기능은 아래와 같다.

    • 데이터 추가/조회/변경/삭제
    • 데이터의 무결성 유지
    • 트랜잭션 관리
    • 데이터의 백업 및 복원
    • 데이터 보안


    자바 웹 프로그램에서 데이터베이스를 사용하려면

         어떤 사전 작업을 해야 할까?



    자바와 데이터베이스를 연동하려면 JDBC(Java DataBase Connectivity) API에 대해서 알아야한다.


    이 API는 자바에서 데이터베이스 관련 작업을 처리할 수 있도록 한다.

    DBMS의 종류의 상관없이 처리할 수 있어서 편리하다. (각각의 DBMS는 JDBC 드라이버를 제공한다.)


    사용하는 DBMS에서 제공하는 드라이버를 설치하면

    JDBC를 통해서 데이터베이스를 사용할 수 있게 된다.


    설치방법- 웹 어플리케이션 디렉터리의 WEB-INF/lib 폴더의 드라이버를 복사해주면 된다.



    ※자바 웹프로그램에서 JDBC의 실행순서 요약

    • JDBC 드라이버 로딩
    • 데이터베이스와 커넥션
    • Statement 객체를 이용한 쿼리 실행
    • Statement, 데이터베이스 커넥션 종료


    1. JDBC 드라이버 로딩

    try{

    Class.forName("JDBC드라이버 클래스의 완전한 이름");

    } catch(ClassNotFoundException ex) {

    }


    2. 데이터베이스와 커넥션

    연결을 위해서는 데이터베이스의 주소(URL)와 아래의 클래스와 메서드가 필요하다.

    java.sql.Connection 클래스

    java.sql.DrivaerManager 클래스의 getConnection()메서드


    DriverManager.getConnection(String jdbcURL);

    DriverManager.getConnection(String jdbcURL, String user, String password);


    위 메서드의 매개변수가 정확하다면 Connection 객체를 리턴한다.


    3. Statement 객체를 이용한 쿼리실행

    conn 변수로 리턴 받은 Connection 객체로 Statement를 객체를 생성한다.

    Statement stmt = conn.createStatement();


    그리고 아래의 메서드에 쿼리문을 query 변수에 담아서 전달하면 쿼리를 실행할 수 있다.


    ResultSet executeQuery(String query) - SELECT 쿼리를 실행

    int executeUpdate(String query) - INSERT, UPDATE, DELETE 쿼리를 실행


    executeQuery() 메서드는 SELECT 쿼리의 결과값을 java.sql.ResultSet 객체에 저장하여 리턴한다.

    executeUpdate() 메서드는 INSERT, UPDATE, DELETE 쿼리의 실행으로 변경된 레코드의 개수를 리턴한다.


    3-1. ResultSet 값 읽어오기

    Resultset 객체에 저장된 쿼리 실행 결과는 먼저 이 클래스가 제공하는 

    next() 메서드와 getXXX() 메서드로 읽어올 수 있다. (XXX 부분은 데이터 타입별로 이름이 달라진다.)


    Resultset은 쿼리의 결과를 행으로 저장하고 커서를 이동하여 각 행의 데이터에 접근한다.

    next() 메서드는 다음행이 존재할 경우 true를 리턴하고 커서를 그 행으로 이동시킨다.

    그리고 getString()메서드로 문자열 타입의 행의 데이터를 읽어올 수 있다.


    예시)

    rs = stmt.executeQuery("select * from 테이블명);

    if(rs.next()) {

    String name = rs.getString("NAME");

    } else {

    }


    3-2. PreparedStatement를 사용한 쿼리 실행

    java.sql.PreparedStatement는 Statement와 동일한 기능을 제공하지만

    SQL의 틀을 미리 생성해 놓고 값을 나중에 지정한다는 점이 다르다.


    예시)

    pstmt = conn.prepareStatement(

    "insert into 테이블명 values(?, ?, ?));

    pstmt.setString(1, memberID);

    pstmt.setString(2, password);

    pstmt.setString(3, name);





    4.  웹 어플리케이션 구동시 자동으로 JDBC 드라이버 로딩하기

    JDBC 드라이버는 한번만 로딩하면 계속 사용할 수 있으므로 

    웹 어플리케이션 시작시(웹 컨테이너 시작시) 한번 로딩하여 모든 JSP페이지에서 사용하도록 만든다.


    먼저 웹 어플리케이션 폴더/src/패키지명 경로에 서블릿 클래스를 생성한다.


    그리고 WEB-INF/lib의 web.xml 파일을 열고 아래 코드를 넣으면

    웹 어플리케이션 시작시 서블릿 클래스가 실행되면서 자동으로 JDBC 드라이버를 로딩한다.


      <servlet>

      <servlet-name>서블릿클래스명</servlet-name>

      <servlet-class>서블릿클래스의 완전한 이름</servlet-class>

      <init-param>

      <param-name>jdbcdriver</param-name>

      <param-value>oracle.jdbc.driver.OracleDriver</param-value>

      </init-param>

      <load-on-startup>1</load-on-startup>

      </servlet>



    6. 커넥션 풀

    JSP 페이지를 실행할때마다 커넥션을 생성하고 닫는다면

    동시 접속자수가 많은 웹 사이트의 전체 성능을 낮추는 원인이 된다.

    이를 해결하기 위해서 커넥션 풀 기법을 사용한다.


    커넥션 풀:

    데이터베이스와 연결된 커넥션을 미리 생성해서 풀(pool)에 저장해 두고 있다가

    필요할때 가져다쓰고 다시 반환하는 기법을 의미한다.


    6.1 DBCP를 이용해서 커넥션 풀 사용하기


    ※오픈 소스 프로젝트인 DBCP API의 사용과정은 아래와 같다.

    • DBCP 관련 jar파일 및 jdbc jar파일 설치하기

    • 커넥션 풀 관련 설정 파일 초기화하기

    • 커넥션 풀 관련 드라이버 로딩하기

    • 커넥션 풀로 부터 커넥션 사용하기


    1.관련 .jar 파일 설치하기

    WEB-INF/lib 경로에 복사한다.

    commons-dbcp-버전.jar

    commons-pool-버전.jar


    2.설정 파일 작성하기

    pool.jocl 파일을 웹 프로젝트 폴더 -> java resource -> src에 생성한다.


    ※생성방법

    마우스 오른쪽클릭 -> new -> other -> general -> 확장자 .jocl로 file 생성

    src에 있는 파일을 이클립스가 자동으로 xml 문서로 처리한다


    -pool.jocl

    <object class="org.apache.commons.dbcp.PoolableConnectionFactory"

    xmlns="http://apache.org/xml/xmlns/jakarta/commons/jocl">


    <object class="org.apache.commons.dbcp.DriverManagerConnectionFactory">

    <string value="데이터베이스 URL"/>

    <string value="접속ID"/>

    <string value="비밀번호"/>

    </object>

    <object class="org.apache.commons.pool.impl.GenericObjectPool">

    <object class="org.apache.commons.pool.PoolableObjectFactory" null="true"/>

    </object>

    <object class="org.apache.commons.pool.KeyedObjectPoolFactory" null="true"/>

    <string null="true"/>

    <boolean value="false"/>

    <boolean value="true"/>

    </object>


    3.커넥션 풀 초기화하기

    DBCP API의 커넥션 풀을 사용하려면 JDBC 드라이버를 로딩해주어야 한다.

    아래와 같은 JDBC 드라이버를 각각 로딩해야한다.


    DBMS 연결에 사용할 JDBC 드라이버

    DBCP API의 JDBC 드라이버 - org.apache.commons.dbcp.PoolingDriver


    위의 2가지 형태의 JDBC 드라이버를 Loader.java처럼 웹 어플리케이션 시작시 

    자동으로 로딩하도록 만든다. 아래 코드는 DBCP API 관련 코드를 제외하면 Loader.java와 동일하다.

    그리고 WEB-INF/lib의 web.xml 파일에 위에 4번에서 설명한 코드를 붙여넣는다.


    -DBCPInit.java


    package util;


    import javax.servlet.http.HttpServlet;

    import javax.servlet.ServletConfig;

    import javax.servlet.ServletException;

    import java.util.StringTokenizer;


    public class DBCPInit extends HttpServlet{

    public void init(ServletConfig config) throws ServletException {

    try {

    String drivers = config.getInitParameter("jdbcdriver");

    StringTokenizer st = new StringTokenizer(drivers, "");

    while(st.hasMoreTokens()) {

    String jdbcDriver = st.nextToken();

    Class.forName(jdbcDriver);

    }

    Class.forName("org.apache.commons.dbcp.PoolingDriver");

    } catch(Exception ex) {

    throw new ServletException(ex);

    }

    }

    }


    4.커넥션 풀로 부터 커넥션 사용하기


    JDBC 드라이버의 URL이 다르다는 점을 제외하고

    일반적인 Connection 생성 코드와 차이가 없으므로 위에서 설명한 내용대로 진행하면 된다.


    예시)

    Connection = null;


    try{

    String jdbcDriver = "jdbc:apache:commons:dbcp:/pool";

    conn = DriverManager.getConnection(jdbcDriver);

    } finally {

    if( conn !=null) try { conn.close(); } catch(SQLException ex) {}

    }


    ※커넥션 풀에서 구한 Connection()에서 close() 메서드를 호출하면 닫히는 것이 아니라

    커넥션 풀로 반환된다.

    '웹프로그래밍 > 기초' 카테고리의 다른 글

    HTTP 요청과 응답 그리고 서블릿 정리  (0) 2018.12.02
    프록시란?  (0) 2018.07.12
    웹 요청 처리에 대한 기본지식  (0) 2018.06.10
    세션(session)과 쿠키(cookie)  (0) 2018.06.09
    페이징  (0) 2018.04.28