티스토리 툴바


posted by Winchester.K 2011/08/18 13:17

// PreparedStatement가 좋긴 좋다

package com.test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import com.db.DBController;

public class TestDb {

 public static void main(String[] args) {

  DBController  dbcon = null;
  Connection   con  = null;
  PreparedStatement pstmt = null;
  ResultSet    rs  = null;
  String filePath = "D:/amail/postman/CodeTest/src/com/docs/test.txt";
  String filePathOut = "D:/amail/postman/CodeTest/src/com/docs/CHARGE.txt";

// 반복시킬 쿼리
  String QUERY_SELECT
   = "SELECT "
   + " SUM(NVL(DECODE(VALUE2,'Y',AMOUNT,0),0)) AS TOTAL, "
   + " SUM(NVL(DECODE(VALUE3,'Y',AMOUNT,0),0)) AS USED, "
   + " SUM(NVL(DECODE(VALUE2,'Y',AMOUNT,0),0)) - SUM(NVL(DECODE(VALUE3,'Y',AMOUNT,0),0)) AS CHARGE "
   + "FROM "
   + " TRADES A, EBCD0030 B  "
   + "WHERE "
   + " TRD_ID < '20110810000000' "
   + " AND USER_ID = ? "
   + " AND CODE_TYPE ='60' "
   + " AND TRD_TYPE = CODE_CODE(+) ";

  BufferedReader br = null;
  String read = null;
  BufferedWriter out = null;

  int i=0;
  try {
  // 커넥션 맺는부분.. 저는 따로 클래스 파일을 만들어 사용했습니다. 필요시 요청해주세요
   dbcon = new DBController();
   con = dbcon.getConnection();
   pstmt = con.prepareStatement(QUERY_SELECT);

   // 버퍼리더와 버퍼라이터 설정
   br = new BufferedReader(new FileReader(new File(filePath)));
   out = new BufferedWriter(new FileWriter(filePathOut));

   // BufferedReader를 이용해서 1라인씩 읽고 출력합니다.
   while((read=br.readLine()) != null){
    pstmt.setString(1, read);

    rs = pstmt.executeQuery();

    if(rs.next()) {
     out.write(read+"\t"+rs.getString("TOTAL")+"\t"+rs.getString("USED")+"\t"+rs.getString("CHARGE"));
     out.newLine();
     System.out.println(++i);  // 찍기용 작업량 확인용
    }
   }

  } catch(Exception e) {
   e.printStackTrace();
  } finally {
   try{
    out.close();
    br.close();
   }catch(Exception e){}
   
   dbcon.release(rs);
   dbcon.release(pstmt);
   dbcon.release(con);
  }
  
  System.out.println("SYSTEM_END");  // 종료확인용 }
}

저작자 표시
posted by Winchester.K 2011/08/10 10:27

<%@ page contentType="text/html;charset=euc-kr" session="false"%>
<%@ page import="java.util.*"%>
<%@ page import="java.sql.*"%>
<%@ page import="kr.co.amail.asp.common.db.*"%>

Statement stmt = null;
ResultSet rs = null;
ConnectionMgr connMgr = null;
Connection con = null;

/* 값의 초기화 */
List resultList = new ArrayList();
Iterator it = null;
Map data = null;
int totalCount = 0;
int maxCount = 0;

try {
    connMgr = new ConnectionMgr();
    con = connMgr.getConnection();
    String query = "SELECT COUNT(*) CNT AS  FROM TABLE_NAME";

    stmt = con.createStatement();
    rs = stmt.executeQuery(selectQuery);

    while(rs.next()) {
    data = new HashMap();
    data.put("count", rs.getString("CNT"));

    totalCount += rs.getInt("CNT");
    maxCount = Math.max(rs.getInt("CNT"),maxCount);
    resultList.add(data);
}
} catch(Exception _ex)  {
} finally {
    DBFunction.release(rs);
    DBFunction.release(stmt);
    connMgr.freeConnection();
}

<html>
  <head>
  </head>

  <body>
    <%=totalCount%>

    <table width="100%" border="1" cellspacing="0" cellpadding="0">
      <tr>
        <td><b>회원수</b></td>
      </tr>
      <%
        if (resultList.size() == 0) {
      %>
      <tr>
        <td height="30" colspan="2" align="center">가입경로별 회원통계가 없습니다.</td>
      <%
        } else {
          it = resultList.iterator();
          while (it.hasNext()) {
            data = (Map) it.next();
      %>
      <tr>
        <td><%=data.get("channel")%></td>
      </tr>
      <%
         }
       }
        %>
    </table>
  </body>
</html>

저작자 표시

':: JAVA > LIST' 카테고리의 다른 글

jsp table에 데이터 뿌리기  (0) 2011/08/10
posted by Winchester.K 2011/08/08 14:24
DB Connection Pool 사용하기

이 문서는 GPL을 따르기에 자유로이 수정, 배포 가능합니다.
작 성 자 : hops(최 호필) 작 성 일 : 2000. 12. 18

[참고 사이트 및 참고 Documentation]
http://developer.java.sun.com/developer/Books/JDBCTutorial/index.html
http://java.sun.com/products/jdbc/articles/package2.html
http://jspschool.com/
http://java.webpd.co.kr/
Resin Documentation


※편의상 경어는 생략합니다. 양해바랍니다.

1. DB Connection Pool 이란?

대부분의 사람들이 DB Connection Pool이란 것을 알고 있을 것이다.
보통의 경우에는 DB에 연결을 하고 결과를 가져온 후에 연결을 끊어 버리게 된다. DB에 연결하는 과정은 시간이 많이 소요되는 Cost가 비싼 연산이다. 물론 퍼포먼스도 많이 떨어진다.

이러한 문제점을 해결하기 위해 DB Connection Pool 이라는 것을 사용한다.
DB Connection Pool이란 DB Connection Pool 매니저가 일정의 컨넥션을 연결하고 있다가, 요청이 들어오면 컨넥션을  할당을 해주고 없으면 기다리게 한다. 요청한 클라이언트는 컨넥션을 다쓰면 다시 반납하는 구조로 이루어 진다.

따라서 속도면이나 퍼포먼스 부분에서 조금은 향상을 바랄수 있을 것이다.


2. 사용방법

JDBC version 2.0에는 2개의 Package가 존재한다.
J2SE 안에 있는 java.sql Package와 J2EE 안에 있는 javax.sql package가 그것이다.
자 이제 하나 하나씩 각각의 패키지에서 Connection Pooling을 어떻게 사용하는지 알아보도록 하자.


2.1 java.sql Package를 이용한 DB Connection Pool

이 패키지를 이용하기 위해서는 Connection Pool의 기능을 하는 클래스를 만들어야 한다.
뭐 원하시는 분들은 직접 만들어도 되지만, Gefion software라는 곳에서 NON-COMMERCIAL용으로 만들어 놨으니 이걸 이용하여도 무방하다. 직접 만드실 분들은 이 소스를 분석하시는 것도 많은 도움이 되실 듯 싶다.

이 소스를 다운받아서 컴파일을 시킨다. 그리고 클래스가 위치한 동일한 디렉토리에 db.properties라는 파일을 만든다.
아래의 내용은 db.properties 파일의 내용이다.

############################# 파일의 내용 ##################################################
drivers 공백으로 분리된 JDBC driver 이름의 리스트
logfile 로그파일의 절대위치

이것 외에 각각의 풀에 대해 다음과 같은 프라퍼티를 설정할 수 있다.
프라퍼티의 이름은 모두 커넥션풀의 이름으로 시작한다.


<poolname>.url 데이타베이스 연결을 위한 JDBC URL
<poolname>.maxconn 가능한 최대 연결 갯수. 0 는 제한 없음을 의미.
<poolname>.user 풀에 사용할 사용자 이름
<poolname>.password 사용자가 쓰는 패스워드
############################## 파일의 끝 ####################################################

참고를 할 수 있는 예제는 다음과 같다.

################################### 예제 db.properties 파일 #################################
dirvers=org.gjt.mm.mysql.Driver
logfile=d:\\java\\resin1.2.0\\log\\DBConnectionManager_log.txt

pool.url=jdbc:mysql://203.238.XXX.XXX:3306/hops
pool.maxconn=10
pool.user=root
pool.password=
###########################################################################################################

다음은 테스트를 해본 JSP 소스이다. 참고하길 바란다.

############################# TestConnectionPool.jsp  ######################################
<%@ page language="java" import="java.sql.*,DBConnectionManager" %>

<%-- DBConnectionManager의 초기화 --%>
<%!
private DBConnectionManager connMgr;
%>

<%-- 하나의 DBConnectionManager의 인스턴스 얻기 --%>
<%!
public void jspInit()
{
connMgr = DBConnectionManager.getInstance();
}
%>

<%
// 컨넥션 풀에서 컨넥션 하나 얻기
Connection con = connMgr.getConnection("pool");

try {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select id, name from customer");
%>

<html>
<body>
<br>
<table border=1 cellspacing=0 width=300>
<tr>
<td align=center bgcolor=gray>
ID
</td>
<td align=center bgcolor=gray>
NAME
</td>
</tr>
<%
while(rs.next()) {
String id= rs.getString(1);
String name = rs.getString(2);
%>
<tr>
<td align=center>
<%=id %>
</td>
<td align=center>
<%= name %>
</td>
</tr>
<%
}
%>
</table>
</body>
</html>
<%
stmt.close();
} catch (java.sql.SQLException e) {
System.out.println(e);
} catch (java.io.UnsupportedEncodingException e) {
System.out.println(e);
} finally
{
//컨넥션 풀에서 얻은 컨넥션 반납
connMgr.freeConnection("pool", con);
}
%>

<%-- 하나의 DBConnectionManager의 인스턴스 반납 --%>
<%!
public void jspDestroy()
{
connMgr.release();
}
%>
############################# End Of TestConnectionPool.jsp ########################################


2.2 javax.sql Package(JDBC 2.0 Optional Package)를 이용한 DB Connecion Pooling

이 패키지는 J2SE안에 포함되어 있지 않고 따로 다운받아야 한다. J2EE를 다운받으면 그 안에 포함되어 있다.
자세한 API들은 J2EE Document를 받아서 보길 바란다. javax.sql 패키지에서는 DataSource Class를 통해
Data Access를 하게 된다. DataSource는 기본적으로 Connection Pool과 분산 Transaction을 지원한다.


2.2.1 DataSource Object Connection

DataSource object는 특정 DBMS나 다른 data source(file과 같은)를 표현한다.

DataSource object 구현의 3가지 방법

1) Basic DataSource implementation
: Pool이나 분산 transaction을 지원하지 않는 표준 Connection object를 생성

2) Connection Pooling을 지원하는 DataSource class
: connection들을 재활용할 수 있는 connection pooling에 관여하는 Connection object를 생성

3) 분산 Transaction을 지원하는 DataSource class
: 둘 이상의 DBMS 서버들에 엑세스하는 분산 트랜잭션에서 사용될 수 있는 Connection object를
생성

JDBC 2.0 API를 지원하는 driver는 최소한 basic DataSource implementation을 포함하여야 한다.
EJB vendor에 의해 공급되는 DataSource class는 거의 다 connection pooling과 distributed transaction 두가지
모두를 지원한다. DataSource object는 다음과 같은 3가지 작업으로 구성되어 deploy된다.

1) DataSource class의 instance 생성
2) properties 셋팅
3) JNDI API를 이용하여 naming service에 등록

위에서 언급한 DataSource object 구현의 3가지 방법 중에서 1)번과 3)번은 참고사이트에서 정보를 얻길 바란다.
여기에서는 Connection Pool에 대해서만 언급한다. Connection Pool을 지원하는 DataSource Deploy는 다음과 같이
사용한다.

먼저 ConnectionPoolDataSource object를 deploy하고 DataSource를 deploy한다. DataSource object는 2개의
properties가 필요하다(description과 dataSourceName). dataSourceName property는 먼저 deploy했던
ConnectionPoolDataSource object의 logical Name이다. ConnectionPoolDataSource와 DataSource object가 deploy된
후에 DataSource.getConnection으로 pooled connection을 얻는다.

예)
########################################################################
ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("jdbc/testDB");
########################################################################

connection을 얻는 예)
########################################################################
try {
Connection con = ds.getConnection("USER","PASSWORD");
} catch (Exception e) {
// Exception 처리
} finally {
if (con != null) con.close();
}
########################################################################

이제는 WebLogic에서 사용하는 것을 봄으로써 좀 더 이해를 해 보자.

Example)WebLogic에서 DB Connection Pool 사용하기

만일 다음과 같이 오라클DB에 Pool을 이용하여 Connection을 얻고자 하는 경우를 생각해 보도록 하자.

Connection getConnection() throws SQLException, NamingException {
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/oraclePool");

return ds.getConnection();
}

위의 코드처럼 사용하고자 하는 경우에는 ejb-jar.xml, weblogic-ejb-jar.xml, weblogic.properties 파일을
수정하면 된다. 먼저 ejb-jar.xml 파일안의 <session> 또는 <entity> 태그안에 다음을 추가한다.

####################### ejb-jar.xml에 추가되는 코드 ####################################
<resource-ref>
<res-ref-name>jdbc/oraclePool</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<resource-ref>
########################################################################################

다음으로 weblogic-ejb-jar.xml 파일 안의 <reference-description> 태그안에 다음을 추가한다.

####################### weblogic-ejb-jar.xml ###################################
<resource-description>
<res-ref-name>jdbc/oraclePool</res-ref-name>
<res-name>weblogic.jdbc.pool.oraclePool</jndi-name>
</resource-description>
#########################################################################################

마지막으로 weblogic.properties 파일 안에 다음을 추가한다.

############################# weblogic.properties ###########################################

weblogic.jdbc.TXDataSource.weblogic.jdbc.pool.oraclePool=oraclePool

################################################################################################

참고로 여기서 oraclePool은 connection Pool명이다.


3. resin에서 DB Pool 사용하기

resin에서 DB Connection Pool을 사용하는 방법은 매우 간단하다. 1.0대 버전과 1.2대 버전에 차이가 있다.
기본적으로 1.0대 버전은 DBPool이라는 caucho사에서 제공하는 클래스를 이용하여 Connection Pool을 구현하고
있고, 2.0대 버전에서는 DataSource를 이용하여 구현하고 있다.

먼저 resin.conf에서 다음과 같이 설정한다.

################################## resin 1.0 ######################################################
<caucho.com>
<dbpool.sql id='test_db' driver="org.gjt.mm.mysql.Driver" url="jdbc:mysql://localhost:3306/test" user="john.doe" password="i8z4oM5"/>
</caucho.com>
################################################################################################

다음은 실제의 소스코드이다. 참고하길 바란다.

######################################## dbpool.jsp ###################################################
<%@ page language=java %>
<%@ page import='java.sql.*' %>
<%@ page import='com.caucho.sql.*' %>
<%
DBPool pool = DBPool.getPool("hops");
Connection conn = pool.getConnection();

ResultSet rs;

try {
Statement stmt = conn.createStatement();
rs = stmt.executeQuery("select * from customer" );
%>
<html>
<body>
<h1>ID : <%= rs.getString(1) %><p>
NAME : <%= rs.getString(2) %></h1>
</body>
</html>
<%
} finally {
conn.close();
}
%>
##########################################################################################################

resin1.2에서부터는 javax.sql Package가 포함됨으로써 Data Access API를 지원한다. 따라서 DataSource를 이용하여 JNDI를 통하여 Connection
Pool을 이용하면 된다. 다음은 그 설정의 예이다. DB는 MySQL을 이용했다. 여기서 hops는 DB명이므로 원하는 DB명으로 바꿔주면 된다.

################################## resin 1.2.0 ######################################################
<resource-ref>
<res-ref-name>jdbc/hops</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<init-param driver-name="org.gjt.mm.mysql.Driver"/>
<init-param url="jdbc:mysql://localhost:3306/hops"/>
<init-param user="root"/>
<init-param password=""/>
<init-param max-connections="20"/>
<init-param enable-transaction="false"/>
</resource-ref>
################################################################################################

다음은 실제의 소스코드이다. 참고하길 바란다.

######################################## dbdsopool.jsp ###################################################
<%@ page language=java %>
<%@ page import='java.sql.*' %>
<%@ page import='javax.sql.*' %>
<%@ page import='javax.naming.*' %>

<%
Context env = (Context) new InitialContext().lookup("java:comp/env");
DataSource source = (DataSource) env.lookup("jdbc/hops");

Connection conn = source.getConnection();
try {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from customer");
%>
<html>
<body>
<h1>ID : <%= rs.getString(1) %><p>
NAME : <%= rs.getString(2) %></h1>
</body>
</html>
<%
} finally {
conn.close();
}
%>
##########################################################################################################

많은 도움이 되었길 바랍니다...

저작자 표시

':: JAVA > DB' 카테고리의 다른 글

DB Connection Pool 사용하기  (0) 2011/08/08