2013. 8. 16. 09:51

● 3항 연산자 활용 태그 속성바꾸기

 

1
2
3
4
5
<select id="numPerPage" class="selectField" onchange="selectList();">
    <option value="10" ${numperpage="="10"" ?="" "selected="selected" ":""}="">리스트10</option>
    <option value="20" ${numperpage="="20"" ?="" "selected="selected" ":""}="">리스트20</option>
    <option value="30" ${numperpage="="30"" ?="" "selected="selected" ":""}="">리스트30</option>
</select>
  서블릿에서 넘긴 parameter에 따라 다음처럼 html 소스가 바뀐다.
1
2
3
4
5
<select id="numPerPage" class="selectField" onchange="selectList();">
    <option value="10">리스트10</option>
    <option value="20">리스트20</option>
    <option value="30" selected="selected">리스트30</option>
</select>



● 자바스크립트에서 문자열

 

1
2
3
4
5
6
7
8
9
10
<script type="text/javascript">
    function ineedId() {
        if(!"${sessionScope.session.userId}"//따옴표가 없으면 if(!)
        {
            alert("로그인이 필요한 서비스입니다.");
            location.href="<%=cp%>/member/login.action";
            return;
        }
    }
</script>
1
2
3
4
5
6
7
<script type="text/javascript">
    function hi() {
        //var params = "content=" + content + "&boardNum=" + ${dto.boardNum};
        var params = "content=" + content + "&boardNum=${dto.boardNum}";
        //위 둘은 같다. 문자열 내부에서도 EL은 상수로 치환됨
    }
</script>



'JSP > Jsp 내장객체' 카테고리의 다른 글

JSP 내장객체의 스코프  (0) 2013.08.16
EL 개요  (0) 2013.08.16
Session  (0) 2013.07.29
Request  (0) 2013.07.29
JSP 개요  (0) 2013.07.29
Posted by 1+1은?
2013. 8. 16. 09:43

EL, Expression Language


목차

■ 개요
■ 작성규칙
■ 연산자
■ 내장객체


■ 개요

 EL은 JSTL 1.0 스펙에서 소개되었던 것으로 JSP 2.0부터 공식적으로 포함되었으며,  JSP 페이지에 사용되는 자바코드를 대신해서 액션태그 엘리먼트

(예:<jsp:setProperty>)의 속성에 값을 지정하는  역할을 한다. 


${object}


request 객체에 전달한 vo라는 자바빈즈에 getEmail() 메소드가 존재할 때 JSP의 스크립릿으로


<%Test vo = (Test)request.getAttribute("vo");%>

<%= vo.getEmail()%>


라 작성했다면 EL은 다음과 같다 :


${vo.address};


졸라 편하다.



■ 작성규칙

EL은 숫자, 문자열, boolean 값과 null 같은 상수 값(리터럴) 들도 포함할 수 있다.⋅

EL은 $ 와 표현식 그리고 브레이스 { }를 사용해서 표현한다.


- 표현 언어(EL)는 항상 『${』 로 시작해서 『}』로 끝난다.

- JSP 스크립트 내부에서 쓸 수 없다. 즉, <%  %>, <%!  %>, <%=  %> 안에는 사용할 수 없다.

- 표현식 안에 연산식도 작성이 가능 하다. 

   ${num  +  1}

- 프로퍼티 접근 연산자 닷(dot(.)) 은 표현 언어(EL)에게 자바 빈이나 컬렉션 객체에서 다음에 오는 이름과 같은 프로퍼티를 찾게 한다.

   ${article['num']  +  1}  or  ${article["num"]  +  1}

- 브라켓 연산자(bracket([ ]) operator) 를 사용해도 된다. 닷(dot(.)) 과 같다. 즉, 브라켓 연산자의 배열 형태로 객체의 변수에 접근한다.



■ 연산자 

.

 빈의 프로퍼티나  맵(Map)의  엔트리 접근 

[]

 배열이나  리스트(List)  엘리먼트 접근 

()

 괄호. 표현식의  연산 순서를  바꿔서 연산하게 할  때

a ? b : c

 EL의 삼항연산자. a가 true면 b, false면 c 

+    -

*   /

%   !

==   !=

<   >

<=   >=

&&   ||

 자바와 같다.

empty

 빈 변수값 체크. null 혹은 빈문자열, 빈배열, 엔트리가 없는 맵이나 컬렉션이면 true 

func(args)

 함수 호출 



■ EL에서 제공하는 내장객체 

● pageScope, requestScope, sessionScope, applicationScope
 : 각 영역 객체들에 대한 컬렉션
${scope.데이터_명}
예를 들어 session 객체로 전달받은 email에 접근할 때, 구문이 다음과 같다면 :
session.setAttribute("email", "noname@site.com"); 

전달받은 데이터에 접근하려면 :
${sessionScope.email} 라고 작성한다.

scope를 명시하지 않으면 requestScope에서 찾는다.

● param
 : 모든 request  파라미터들을  문자열로 가진 컬렉션(request.getParameter() 메소드) 
${param.데이터_명} 
혹은 ${param["데이터_명"]}
param은 html의 form을 통해 입력된 데이터를 가져올 때 사용한다.  

<form action="test2.jsp" method="post">
<input type="text" name="num"><br/>
<input type="submit" value="보내기">

위 폼에서 넘어온 num을 찾으려면 :
${param.num}

● paramValues 
 : 모든 request 파라미터들을 파라미터당 문자열 배열로 가진 컬렉션 
${paramValues.데이터_명[0]},  ${paramValues["데이터_명"][0]})
form을 이용한 입력 중 checkbox, select 등 같은 name 애트리뷰트를 가진 데이터를 가져올 때는 paramValues를 사용한다. 
사용 형식은 param과 비슷하나 여러 개의 입력 값이 있으므로 배열 형태가 된다

<form action="test2.jsp" method="post">
<input type="checkbox" value="first_value" name="ck"/>
<input type="checkbox" value="first_value" name="ck"/>
<input type="submit" value="보내기">

위 폼에서 넘어온 첫번째 값을 찾으려면 :
${paramValues.ck[0]}

배열 순서는 form 태그에 작성 된 순서를 따른다.

● cookie
 : cookie는 웹 브라우저가 웹 서버로 보낸 쿠키를 가져올 때 사용한다.
${cookie.쿠키_명}  
혹은 ${cookie["쿠키_명"]}
주의 할 것은 반환되는 타입이 쿠키의 값이 아니라 쿠키 객체라는 점이다.  
따라서 쿠키의 값을 출력하기 위해서는 :

${cookie.쿠키_명.value  }  
혹은  ${cookie["쿠키_명"]["value"]} 
라고 해주어야 한다. 
쿠키의 값 대신 쿠키의 다른 정보를 얻기 위해 쿠키명 뒤에  .domain  .path  .maxAge 등을 사용할 수도 있다.

● initParam
  : 모든 어플리케이션의 초기화 파라미터의 이름의 컬렉션
 ${initParam.파라미터_명} 
혹은 ${initParam["파라미터_명"]}
initParam은 웹 애플리케이션의 초기화 파라미터를 가져오는데 사용한다. 
이 값을 얻기 위해서는 해당 이름의 초기화 파라미터가 web.xml 에 등록되어 있어야 한다.

● pageContext
  : 현재 페이지를 위한  javax.servlet.jsp.PageContext.  JSP 페이지의 환경 정보
${pageContext.메서드_명}
혹은 ${pageContext.메서드_명}
⋅pageContext는 java.servlet.jsp.PageContext 클래스 타입의 객체로, 이 클래스에 속하는 get 메소드들의 호출에 사용된다. 
그 중에서도 파라미터가 사용되지 않는 메소드들만 실행할 수 있다. 사용 형식은  pageContext 뒤에 마침표나 대괄호를 붙혀 사용하나, 메소드 명에서 get을 버리고 난 후, 가장 첫 문자를 소문자로 고쳐 사용한다.

PageContext 클래스의  getRequest 메소드를 사용한다고 하면 :

${pageContext.request} 
혹은 ${pageContext["request"]} 
의 형식이 된다. 각 메소드의 리턴 값은 각각의 객체가 돌아오므로 필요한 필드를 불러와 출력할 수 있다.

⋅request.getContextPath() 가져오기  :  ${pageContext.request.contextPath}
⋅URI : ${pageContext.request.requestURI}

● header, headerValues
 : HTTP 요청 헤더들을 문자열이나 문자열배열로 가진 컬렉션 
 ${header["헤더_명"]}
자바의 식별자 명명규칙을 따르지 않는 헤더는 반드시 위의 형식으로 가져와야 한다.
HTTP 요청 메시지 안에 같은 이름의  HTTP 헤더가 둘 이상 있는 경우는  headerValues 내장 객체를 사용한다. 사용 형식은 paramValues 의 형식과 같다.


'JSP > Jsp 내장객체' 카테고리의 다른 글

JSP 내장객체의 스코프  (0) 2013.08.16
HTML 문서에서 인자로 사용  (0) 2013.08.16
Session  (0) 2013.07.29
Request  (0) 2013.07.29
JSP 개요  (0) 2013.07.29
Posted by 1+1은?
2013. 8. 16. 09:42


 String path = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+cp;


위에서 각 메서드는


getScheme() → http

getServerName() → localhost

getServerPort() → 9090

getContextPath() → test


처럼 값을 가져오며 아래처럼 출력한다.


http://localhost:9090/test

'JSP > JspServlet' 카테고리의 다른 글

서블릿에서 out.print()  (0) 2013.08.16
tag : core  (0) 2013.08.16
None Annotation 스프링 MVC 예제 (abstract, multiaction)  (0) 2013.07.29
MVC 관련 핸들러 매핑 및 컨트롤러  (0) 2013.07.29
액션 태그와 커스텀 태그  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 31. 16:01


examples.zip

출처 : http://www.oesmith.co.uk/morris.js/index.html


jQuery 차트를 만드는 방법


1. 추가

1
2
3
4
<link rel="stylesheet" href="http://cdn.oesmith.co.uk/morris-0.4.3.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>

2. <div>

1
<div id="myfirstchart" style="height: 250px;"></div>

3. <script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var nReloads = 0;
function data(offset) {
  var ret = [];
  for (var x = 0; x <= 360; x += 10) {
    var v = (offset + x) % 360;
    ret.push({
      x: x,
      y: Math.sin(Math.PI * v / 180).toFixed(4),
      z: Math.cos(Math.PI * v / 180).toFixed(4)
    });
  }
  return ret;
}
var graph = Morris.Line({
    element: 'graph',
    data: data(0),
    xkey: 'x',
    ykeys: ['y', 'z'],
    labels: ['sin()', 'cos()'],
    parseTime: false,
    ymin: -1.0,
    ymax: 1.0,
    hideHover: true
});
function update() {
  nReloads++;
  graph.setData(data(5 * nReloads));
  $('#reloadStatus').text(nReloads + ' reloads');
}
setInterval(update, 200);


4. 실행화면



기본적인 꺽은선 그래프이다.


추가적인 그래프를 원할 경우 examples.zip의 samaple파일을 확인해보자.



'javascript > jQuery' 카테고리의 다른 글

chart 관련 사이트모음  (1) 2013.07.31
Posted by 1+1은?
2013. 7. 31. 13:16

http://codegeekz.com/best-jquery-chart-libraries-for-building-interactive-charts/


chart.Js : http://www.chartjs.org/docs/


Chart.js-master.zip


xCharts : http://tenxer.github.io/xcharts/


xcharts-master.zip


jqPlothttp://www.jqplot.com/


jquery.jqplot.1.0.8r1250.zip


wijmo javascript api : http://wijmo.com/docs/wijmo/webframe.html#Linechart.html


google : https://developers.google.com/chart/?hl=ko&csw=1


최신모음 : http://socialcompare.com/en/comparison/javascript-graphs-and-charts-libraries


'javascript > jQuery' 카테고리의 다른 글

jQuery moris.js(free-license)  (0) 2013.07.31
Posted by 1+1은?
2013. 7. 30. 15:49

출처 : http://tomcat.apache.org/tomcat-7.0-doc/virtual-hosting-howto.html


renstimpy 라는 두개의 Host-name 을 가진 development-host 가 있다고 가정된 상태에서 진행된다.

톰캣의 한가지 instance가 실행될때 $CATALINA_HOME 는 /usr/local/tomcat/의 경로를 참조한다.


또한 UNIX-Style의 경로 구분 및 명령을 사용하여 수정할 수도 있다.


server.xml

1
2
3
4
<engine name="Catalina" defaulthost="ren">
    <host name="ren" appbase="renapps">
    <host name="stimpy" appbase="stimpyapps">
</host></host></engine>

각각의 호스트의 appBase 아래의 디렉토리 구조가 서로 중복되지 않아야 한다.


webapps 디렉토리


각각의 가상 호스트 디렉토리를 생성한다.

1
2
mkdir $CATALINA_HOME/renapps
mkdir $CATALINA_HOME/stimpyapps


Context 구성 - 1


$CATALINA_HOME/renapps/ROOT/META-INF/context.xml


Context 구성 - 2


$CATALINA_HOME/conf/Catalina 와 일치하는 가장 호스트를 만든다.


1
2
mkdir $CATALINA_HOME/conf/Catalina/ren
mkdir $CATALINA_HOME/conf/Catalina/stimpy


마지막 디렉토리의 이름이 "Catalina" 속성을 나타낸다.


추가 : 

1
2
$CATALINA_HOME/conf/Catalina/ren/ROOT.xml
$CATALINA_HOME/conf/Catalina/stimpy/ROOT.xml


만약 각 호스트에 톰캣의 관리자 web application을 사용하려는 경우에는 

1
2
3
cd $CATALINA_HOME/conf/Catalina
cp localhost/manager.xml ren/
cp localhost/manager.xml stimpy/


부분도 추가해야 한다.

'DBMS' 카테고리의 다른 글

JNDI 톰캣 구성의 예(직역)  (0) 2013.07.30
JDBC Connection Pool  (1) 2013.07.30
Posted by 1+1은?
2013. 7. 30. 15:01

출처 : http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html


데이터 소스를 사용하는 간단한 예 : 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.sp.jakarta;
 
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
 
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
 
 
 
public class SimplePOGOExample {
 
    public static void main(String[] args) throws Exception{
        PoolProperties p =new PoolProperties();
        p.setUrl("jdbc:mysql://localhost:3306/mysql");
        p.setDriverClassName("com.mysql.jdbc.Driver");
        p.setUsername("root");
        p.setPassword("1234");
        p.setJmxEnabled(true);
        p.setTestWhileIdle(false);
        p.setTestOnBorrow(true);
        p.setValidationInterval(30000);
        p.setTimeBetweenEvictionRunsMillis(30000);
        p.setMaxActive(100);
        p.setInitialSize(10);
        p.setMaxWait(10000);
        p.setRemoveAbandonedTimeout(60);
        p.setMinEvictableIdleTimeMillis(30000);
        p.setMaxIdle(10);
        p.setLogAbandoned(true);
        p.setRemoveAbandoned(true);
        p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState" +
                              "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
        DataSource dataSource = new DataSource();
        dataSource.setPoolProperties(p);
         
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery("select * from user");
            int cnt = 1;
            while (rs.next()){
                System.out.println((cnt++) + ". HOST:" + rs.getString("HOST") +
                        " User:" + rs.getString("User") + " Password:" + rs.getString("Password"));
            }
            rs.close();
            st.close();
        } finally {
            if(conn != null)
                try {
                    conn.close();
                } catch (Exception e) {
                }
        }
    }
}

JNDI조회를 위한 resource를 구성하는 방법(<br/> 제외)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<resource name="jdbc/TestDB" <br="">
          auth="Container"
          type="javax.sql.DataSource"         
          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
          testWhileIdle="true"
          testOnBorrow="true"
          testOnReturn="false"
          validationQuery="SELECT 1"
          validationInterval="30000"
          timeBetweenEvictionRunsMillis="30000"
          maxActive="100"
          minIdle="10"
          maxWait="10000"
          initialSize="10"
          removeAbandonedTimeout="60"
          removeAbandoned="true"
          logAbandoned="true"
          minEvictableIdleTimeMillis="30000"
          jmxEnabled="true"         
          jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;           
          org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
          username="root"
          password="password"
          driverClassName="com.mysql.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/mysql"/>
</resource>


Asyncronous Connection Retrieval (비동기 연결 검색)


톰캣 JDBC pool connection은 라이브러리에 스레드를 추가하지 않고도 비동기 연결 검색을 지원한다.

이것은 추후의 <Connection> getConnectionAsync() </Connection>을 호출하여 데이터 소스에 메서드를 추가하는 작업을 수행한다.

이러한 비동기 검색을 사용하기 위해서는 두가지 조건이 충족되어야 한다.


fairQueue property를 true로 하고, org.apache.tomcat.jdbc.pool.DataSource 데이터 소스를 캐스팅 해야한다.


비동기 기능을 사용하는 예 : 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Connection con = null;
  try {
    Future<connection> future = datasource.getConnectionAsync();
    while (!future.isDone()) {
      System.out.println("Connection is not yet available. Do some background work");
      try {
        Thread.sleep(100); //simulate work
      }catch (InterruptedException x) {
        Thread.currentThread().interrupt();
      }
    }
    con = future.get(); //should return instantly
    Statement st = con.createStatement();
    ResultSet rs = st.executeQuery("select * from user");
</connection>


'DBMS' 카테고리의 다른 글

Virtual Hosting and Tomcat (가상 호스팅과 톰캣) - (직역)  (0) 2013.07.30
JDBC Connection Pool  (1) 2013.07.30
Posted by 1+1은?
2013. 7. 30. 14:31

Spring

1.  SpringFramework ?

-   정의

부품을 조립해주는lib 또는framework  lib 들이 모이면

framework(재사용하는 ) 된다.

요구명세서(목록) 주면 객체도 생성하고 조립까지 해준다.

생성순서는Big -> small  형식이 아니라 small 에서big  순서대로

ex)로봇을 생성할  손가락-> -> 팔뚝-> -> 몸통-> 전체  형식

-    


    

위와 같이 Core 부분의IoC Container Spring 핵심이고, IoC에는DI 있으며 이것을좀더 세부적으로 나눈다면Setter Injection, Constructor Injection, Method Injection 등으로 나눌  있다.

 

2.  SpringFramework 장점

-   경량컨테이너

:  전체 스프링의 크기는 1MB 남짓  하나의JAR파일,스프링에 의해 발생하는 부하는 무시해도 되는 수준

객체의 라이프 사이클 관리,JAVA EE 구현을 위한 다양한 API 제공

-   DI(Dependency Injection), AOP(AspectOriented Programming), POJO(Plain Old Java Object) 지원

-   다양한 API와의 연동 지원을 통한JAVA EE 구현 가능 

 

3.  Spring 주요특징

-   DI(의존성 주입)/ AOP(관점지향)/ MVC(JDBC코딩)

-   통합(struts, spring, Mybatis, hibenate)

-   Transaction / IOC(제어의 역행,역제어)

 

4.  POJO(PlainOld Java Object): 특별한 요구사항을 따르지 않은 평범한 자바객체

 

5.  IOC컨테이너

-   Spring으로 만든 것을IOC 컨테이너에 보관하는데,보관하고 있다가 사용자가 달라고 요청할 시에만 주는 형식이다.



출처 : http://blog.naver.com/jjijilx2?Redirect=Log&logNo=60187998892


'Framework > Spring' 카테고리의 다른 글

Annotation_Spring_MVC_2  (0) 2013.07.29
Annotation_Spring_MVC_1  (0) 2013.07.29
Annotation  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 30. 14:17

MySQL에서 DB에 데이터를 저장하고 리스트로 확인했을때 한글깨지는 현상이 생긴다.


MySQL콘솔로 가서  show variables like 'c%'; 를 실행 하면



C:\Program Files\MySQL\MySQL Server 5.1의 my.ini 를 열어 캐릭터 설정을 바꾼다.


[client]

default-character-set=utf8


[mysql]

default-character-set=utf8


[mysqld]

default-character-set=utf8


바꾼후 (제어판  - 관리도구 - 서비스 - MySQL)로 가서 서버 재가동


이후 아까와 같이 치면 latin1 -> utf-8로 바껴있을 것이다.


그리고 테이블 생성할때 CHARSET=utf8로 해야한다.



1
2
3
4
5
6
7
8
create table users(
    num int primary key AUTO_INCREMENT,
    userid VARCHAR(10),
    password VARCHAR(10),
    nickname VARCHAR(10),
    birthday date,
    email VARCHAR(20)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;



이후 데이터를 너보니....



잘나온다...

'DBMS > MySQL' 카테고리의 다른 글

MYSQL 에서 그룹함수(group by)  (0) 2013.07.29
숫자관련 데이타형에 문자형식으로 insert하기  (0) 2013.07.29
Mysql에서의 null값 고찰  (0) 2013.07.29
MYSQL 성능 향상 정리  (0) 2013.07.29
초급QUERY  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 30. 10:33


boardpool.jocl

참고 : http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

       : http://blog.naver.com/chocolleto?Redirect=Log&logNo=30084743153



1. 커넥션 풀 (Connection Pool)
 
○ 정의

- 데이터베이스와 연결된 커넥션을 미리 만들어 풀(pool)이란 저장소에 저장해 두고 있다가 필요할 때에 커넥션 풀에서 가져다 쓰고
   다시 풀에 반환하는 기법.
- 미리 접속을 하여 메모리에 접속 객체를 저장해 두는 기술.

○ 특징

- pool 속에 미리 커넥션이 생성되어 있기 때문에 커넥션을 생성하는데 드는 연결 시간이 소비되지 않음.
   (어플리케이션의 실행속도가 빨라짐.)
- 커넥션을 계속해서 재사용하기 때문에 생성되는 커넥션 수가 많지 않음.
   (동시 접속자수가 몰려도 웹 어플리케이션이 쉽게 다운되지 않음.)

2. DBCP (Database Connection Pool)

○ 정의

- Database Connection Pool을 구현한 것. (미리 접속을 하여 메모리에 접속 객체를 저장해 두는 기술.)
- Commons DBCP : apache에서 개발한 커넥션 풀 기능을 제공하는 API.

○ 특징
- JDBC의 Connection을 생성하고 사용하지 않는 Connection을 관리하여 Connection의 재사용을 높일 수 있음.

○ 처리 과정

1) DBCP 관련 jar 파일 및 JDBC 드라이버 jar 파일 설치.
2) 커넥션 풀 관련 설정 파일 초기화.
3) 커넥션 풀 관련 드라이버 로딩.
4) 커넥션 풀로부터 커넥션 사용.

○ Web Application에서 DBCP 설정
    
■ 필요한 jar 파일 복사

○ jar 파일

- jakarta commons DBCP
- jakarta commons Collections (Pool이 사용)
- jakarta commons Pool (DBCP가 사용)
(jakarta : http://jakarta-k.sourceforge.net/)      

○ 다운로드

○ 파일 위치

- /WEB-INF/lib 폴더에 위치.

■ 커넥션 풀 설정 파일 작성.
      
○ 특징

- 커넥션 풀에 대한 설정 파일. 
- 파일명 : pool.jocl (파일 이름은 사용자가 지정.)
      
○ 설정 파일 위치

- DBCP API는 클래스패스로부터 설정 파일을 읽어오므로 클래스패스에 위치해 있어야 함.
  (/WEB-INF/classes 폴더 혹은 /build/classes 폴더)

○ boardpool.jocl

 

<object class = "org.apache.commons.dbcp.PoolableConnectionFactory"
    xmlns = "http://apache.org/xml/xmlns/jakarta/commons/jocl">
   
    <!-- mysql 접속. -->
    <object class = "org.apache.commons.dbcp.DriverManagerConnectionFactory">
        <string value = "jdbc:mysql://localhost:3306/board" />
        <string value = "root" />
        <string value = "1111" />
  </object>

  <object class = "org.apache.commons.pool.impl.GenericObjectPool">
    <object class ="org.apache.commons.pool.PoolableObjectFactory" null="true" />
        <int value  =  "10"/>  <!-- maxActive -->
        <byte value = "1"/>  <!-- whenExhaustedAction -->
        <long value = "10000"/>  <!-- maxWait -->
        <int value  = "10"/>  <!-- maxIdle -->     
        <int value  = "3"/>  <!-- minIdle -->     
        <boolean value = "true"/>  <!-- testOnBorrow -->
        <boolean value = "true"/>  <!-- testOnReturn -->
        <long value    = "600000"/>  <!-- timeBetweenEvictionRunsMillis -->
        <int value = "5"/>  <!-- numTestsPerEvictionRun -->
        <long value = "3600000"/>  <!-- minEvictableIdleTimeMillis -->
        <boolean value ="true"/>  <!-- testWhileIdle -->
    </object>

    <object class = "org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory" null="true" />
    <string null = "true" />
    <boolean value = "false" />
     <boolean value = "true" />
</object>


- 주석을 지우고 실행할 것.
- 대소문자 확실히 구분.
        
● GenericObjectPool

- 커넥션 풀의 속성과 관련된 부분.
- API : http://commons.apache.org/pool/api-1.6/index.html
          
□ 속성

속성설명
maxActive커넥션 풀이 제공할 최대 커넥션 개수
whenExhaustedAction커넥션 풀에서 가져올 수 있는 커넥션이 없을 때 어떻게 동작할지를 지정한다. 1일 경우 maxWait 속성에서 지정한 시간만큼 커넥션을 구할 때 까지 기다리며, 0일 경우 에러를 발생시킨다. 2일 경우에는 일시적으로 커넥션을 생성해서 사용한다.
maxWaitwhenExhaustedAction 속성의 값이 1일 때 사용되는 대기 시간. 단위는 1/1000초이며, 0 보다 작을 경우 무한히 대기한다.
maxIdle사용되지 않고 풀에 저장될 수 있는 최대 커넥션 개수. 음수일 경우 제한이 없다.
minIdle사용되지 않고 풀에 저장될 수 있는 최소 커넥션 개수.
testOnBorrowtrue일 경우 커넥션 풀에서 커넥션을 가져올 때 커넥션이 유효한지의 여부를 검사한다.
testOnReturntrue일 경우 커넥션 풀에 커넥션을 반환할 때 커넥션이 유효한지의 여부를 검사한다.
timeBetweenEvctionRunsMillis사용되지 않은 커넥션을 추출하는 쓰레드의 실행 주기를 지정한다. 양수가 아닐 경우 실행되지 않는다. 단위는 1/1000 초이다.
numTestsPerEvictionRun사용되지 않는 커넥션을 몇 개 검사할지 지정한다.
minEvictableIdleTimeMillis사용되지 않는 커넥션을 추출할 때 이 속성에서 지정한 시간 이상 비활성화 상태인 커넥션만 추출한다. 양수가 아닌 경우 비활성화된 시간으로는 풀에서 제거되지 않는다. 시간 단위는 1/1000초이다.
testWhileIdletrue일 경우 비활성화 커넥션을 추출할 때 커넥션이 유효한지의 여부를 검사해서 유효하지 않은 커넥션은 풀에서 제거한다.

 

□ 속성 지정시 고려사항


■ maxActive

- 사이트의 최대 커넥션 사용량을 기준으로 지정.
- 동시 접속자 수에 따라서 지정.
            

■ minIdle
- 사용되지 않는 커넥션의 최소 개수를 0으로 지정하면 풀에 저장된 커넥션의 개수가 0이 될 수 있으며, 이 경우 커넥션이 필요

   할때 다시 커넥션을 생성하게 됨. (최고 개수는 5개 정도로 지정.)
            

■ timeBetweenEvctionRunsMillis
- 이 값을 알맞게 지정해서 사용되지 않는 커넥션을 풀에서 제거하는 것이 좋음.
- 커넥션의 동시 사용량은 보통 새벽에 최저이며, 낮 시간대에 최대.
  (최대 상태에 접어 들었다가 최소 상태로 가게 되면 풀에서 사용되지 않는 커넥션의 개수가 점차 증가.)

- 사용되지 않는 커넥션은 일정 시간 후에 삭제 되도록 하는 것이 좋음. 
  (보통 10 ~20분 단위로 사용되지 않는 커넥션을 검사하도록 지정하는 것이 좋음.)
      

■ testWhileIdle
- 사용되지 않는 커넥션을 검사할 때 유효하지 않은 커넥션은 검사하는 것이 좋음.

■ 드라이버 로드 프로그램 작성
      

○ HttpServlet을 상속받아 초기화.

- 서블릿이 초기에 실행될 때 실행되는 init() 메소드에 작성.
- jsp 페이지에서 DB를 사용하는 부분을 작성할 때 유용. (서버가 실행될 때 한 번만 실행되기 때문에.)
- 자바 파일을 작성한 다음 서블릿 설정파일인 web.xml에 반드시 추가.
        

● 예제


/* DBConInit.java */


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package test.connection;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
 
public class DBConInit extends HttpServlet {
     
    @Override
    public void init(ServletConfig config) throws ServletException {
         
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Class.forName("org.apache.commons.dbcp.PoolingDriver");
            System.out.println("Driver connection success");
        }catch(Exception e) {
            throw new ServletException(e);
        }
         
    }
 


/* web.xml */

[출처] | commons | DBCP|작성자 외계인셩


1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!--?xml version="1.0" encoding="UTF-8"?-->
    <display-name>Board</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
 
    <servlet>
        <servlet-name>DBConInit</servlet-name>
        <servlet-class>test.connection.DBConInit</servlet-class>
        <load-on-startup>1</load-on-startup> <!-- 로드되는 순서 지정. -->
    </servlet>
 
</web-app> 


/* dbcpTest.jsp */

[출처] | commons | DBCP|작성자 외계인셩


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
 
 
<%@ page import="java.sql.*"%>
 
<%
    Connection con = null;
 
    con = DriverManager.getConnection("jdbc:apache:commons:dbcp:boardpool");
     
    if(con == null) {
        out.print("connection is fail.");
    } else {
        out.print("connection is success");
        con.close();
    }
     
%>


[출처] | commons | DBCP|작성자 외계인셩





 DAO 사용 프로그램 작성



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.chocolleto.board.db;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
 
/**
 * DB Connection 하는 Singleton class.
 *
 * @author Administrator
 *
 */
public class DBUtils {
 
    private static final String DBCP_POOLING_DRIVER = "org.apache.commons.dbcp.PoolingDriver";
    private static final String MYSQL_JDBC_DRIVER = "com.mysql.jdbc.Driver";
    private static final String JDBC_URI = "jdbc:apache:commons:dbcp:/boardpool";
     
    // 자기 스스로에 대한 인스턴스 생성. (생성자가 private이기 때문.)
    private static volatile DBUtils instance = null;
 
    private DBUtils() throws Exception {
        try {
            Class.forName(MYSQL_JDBC_DRIVER);
            Class.forName(DBCP_POOLING_DRIVER);
        } catch (Exception e) {
            throw new Exception("Failed to create JDBC drivers.", e);
        }
    }
 
    public static DBUtils getInstance() throws Exception {
        if (instance == null) {
            // 클래스를 생성하려면 클래스 자체에 대해 접근해야하므로 동기화를 걸어줌.
            synchronized (DBUtils.class) {
                if (instance == null) {
                    instance = new DBUtils();
                }
            }
        }
        return instance;
    }
     
    public Connection getConnection() throws SQLException {
        return DriverManager.getConnection(JDBC_URI);
    }

/* UserDAO.java */

[출처] | commons | DBCP|작성자 외계인셩


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
package com.chocolleto.board.user;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
 
import com.chocolleto.board.db.DBUtils;
import com.chocolleto.board.user.model.User;
 
/**
 * @author Administrator
 *
 */
public class UserDAO {
    private DBUtils db;
    // private Logger log = Logger.getLogger(UserDAO.class);
     
    public UserDAO() throws Exception {
        // DB를 관리하는 객체의 인스턴스를 얻어온다.
        db = DBUtils.getInstance();
    }
 
    /**
     * 사용자 등록
     *
     * @param user
     * @throws SQLException
     */
    public void insertUser(User user) throws SQLException {
 
        String sql = "insert into users(userid, password, nickname, birthday, email)"
                + "values(?,?,?,?,?)";
 
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
        String birth;
        if (user.getBirthday() == null) {
            birth = null;
        } else {
            birth = dateformat.format(user.getBirthday());
        }
 
        Connection con = null;
        try {
            con = db.getConnection();
            PreparedStatement st = con.prepareStatement(sql);
 
            st.setString(1, user.getUserid());
            st.setString(2, user.getPassword());
            st.setString(3, user.getNickname());
            st.setString(4, birth);
            st.setString(5, user.getEmail());
 
            st.executeUpdate();
            st.close();
        } catch (SQLException e) {
            throw e;
        } finally {
            if (con != null) {
                try {
                    // 컨넥션은 익셉션이 발생하더라도 항상 close() 될수 있도록 finally 에서 처리한다
                    con.close(); // 실제 컨넥션을 close하는게 아니라 가지고 있던 MySQL의 컨넥션을 풀에 반환.
                } catch (SQLException e) {
                    // 컨넥션을 닫을때 생기는 문제는 무시한다
                }
            }
        }
 
    }
 
    /**
     * 사용자 정보 수정
     *
     * @param user
     * @throws SQLException
     */
    public void updateUser(User user) throws SQLException {
 
        String sql = "update users set password=?,nickname=?,birthday=?,email=?"
                + " where userid=?";
 
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
        String birth;
        if (user.getBirthday() == null) {
            birth = null;
        } else {
            birth = dateformat.format(user.getBirthday());
        }
 
        Connection con = null;
        try {
            con = db.getConnection();
            PreparedStatement st = con.prepareStatement(sql);
 
            st.setString(1, user.getPassword());
            st.setString(2, user.getNickname());
            st.setString(3, birth);
            st.setString(4, user.getEmail());
            st.setString(5, user.getUserid());
 
            st.executeUpdate();
            st.close();
        } catch (SQLException e) {
            throw e;
        } finally {
            if (con != null) {
                try {
                    // 컨넥션은 익셉션이 발생하더라도 항상 close() 될수 있도록 finally 에서 처리한다
                    con.close();
                } catch (SQLException e) {
                    // 컨넥션을 닫을때 생기는 문제는 무시한다
                }
            }
        }
    }
 
    /**
     * 사용자 삭제
     *
     * @param userid
     * @throws SQLException
     */
    public void deleteUser(String userid) throws SQLException {
 
        String sql = "delete from users where userid=?";
        Connection con = null;
        try {
            con = db.getConnection();
            PreparedStatement st = con.prepareStatement(sql);
 
            st.setString(1, userid);
 
            st.executeUpdate();
            st.close();
        } catch (SQLException e) {
            throw e;
        } finally {
            if (con != null) {
                try {
                    // 컨넥션은 익셉션이 발생하더라도 항상 close() 될수 있도록 finally 에서 처리한다
                    con.close();
                } catch (SQLException e) {
                    // 컨넥션을 닫을때 생기는 문제는 무시한다
                }
            }
        }
    }
 
    /**
     * 사용자 검색.
     *
     * @param userid
     * @param password
     * @throws SQLException
     */
    public User selectUser(String id) throws SQLException {
 
        String sql = "select * from users where userid=?";
        Connection con = null;
        User user = null;
        try {
            con = db.getConnection();
            PreparedStatement st = con.prepareStatement(sql);
 
            st.setString(1, id);
 
            ResultSet rs = st.executeQuery();
 
            if (!rs.next()) {
                // 검색된 내용이 없으면 회원이 아니므로 null을 반환.
                rs.close();
                st.close();
            } else {
                // 검색된 내용이 있으면 검색된 내용을 user에 저장.
                user = new User();
                user.setUserid(rs.getString("userid"));
                user.setPassword(rs.getString("password"));
                user.setNickname(rs.getString("nickname"));
                user.setBirthday(rs.getDate("birthday"));
                user.setEmail(rs.getString("email"));
            }
 
            rs.close();
            st.close();
        } catch (SQLException e) {
            throw e;
        } finally {
            if (con != null) {
                try {
                    // 컨넥션은 익셉션이 발생하더라도 항상 close() 될수 있도록 finally 에서 처리한다
                    con.close();
                } catch (SQLException e) {
                    // 컨넥션을 닫을때 생기는 문제는 무시한다
                }
            }
        }
 
        return user;
    }
}



'DBMS' 카테고리의 다른 글

Virtual Hosting and Tomcat (가상 호스팅과 톰캣) - (직역)  (0) 2013.07.30
JNDI 톰캣 구성의 예(직역)  (0) 2013.07.30
Posted by 1+1은?