블로그 이미지
외곈

Notice

Recent Post

Recent Comment

Recent Trackback

Archive

calendar

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
  • total
  • today
  • yesterday
2011. 3. 9. 16:01 Job/정리
실수로 TEST라는 테이블의 데이터를 삭제했다고 했을때

CREATE TABLE BACKUP
AS
SELECT * FROM TEST AS OF TIMESTAMP
(SYSTIMESTAMP-INTERVAL '30' MINUTE);

BACKUP 이라는 테이블을 조회하면 삭제된 데이터가 들어있음.

다시
INSERT INTO TEST SELECT * FROM BACKUP;

하고 커밋~
posted by 외곈
2010. 5. 18. 16:29 Job/정리

IE
element.attachEvent('onclick', function(){
alert(1);
}, false);

기타 표준브라우저
element.addEventListener('click', function(){
alert(1);
}, false);

add하는 펑션이 틀림과
이벤트가 틀림에 주의(IE = onclick, 기타 = click)
posted by 외곈
2009. 10. 12. 15:28 Job/정리
ALTER TABLE TABLE ALTER COLUMN SET DATA TYPE [CHAR/VARCHAR]
posted by 외곈
2009. 6. 3. 20:00 Job/정리

HP-UX에서 NFS설정하는 방법은 두 가지가 있다. 하나는 SAM으로, 하나는 /etc/rc.config.d/nfsconf로 하는 방법이다.

 

일단 nfs 데몬을 띄운다.

# /sbin/init.d/nfs.core start

# /sbin/init.d/nfs.client start

 

1. sam으로 export, import 설정 - 아래의 순서로 진행한다.

 

 

NFS 서버로 사용하려면 Exported Local File Systems를 선택하고, NFS Client로 사용하려면 Mounted Remote File Systems를 선택한다.

 

아래는 NFS서버를 선택한 화면이다. Export할 디렉토리를 선택하고, NFS Server를 enable한다.

 

 

2. 수동으로 설정
1) /etc/rc.config.d/nfsconf 파일에 import 하고 싶으면 client 1, export 하고 싶으면 server 1로 설정한다. (자세한 명령은 man exports 참조)

예) # cat /etc/exports
/디렉토리 -root=호스트명

2) 부팅할 때, /etc/exports 파일 참고해서 export 할 디렉토리를 지정한다.

 

3) /etc/rc.config.d/nfsconf 파일을 참고해서 데몬을 자동으로 start 하나, 수동으로 start 하고 싶으면, 위에 언급한 데로 /sbin/init.d/nfs.core start|stop, /sbin/init.d/nfs.client start|stop 명령을 사용한다.

 

3. NFS client에서의 mount 방법

# mount (-F nfs) -o soft NFS서버:/디렉토리 /로컬디렉토리

 : -o soft 는 서버와 통신 끊어졌을 때 끊어버림. 디폴트 -o hard 는 NFS서버와 계속 연결시도해서 NFS서버와의 연결이 끊어졌을 때 서버 hang이 발생할 가능성이 많음

[출처] HP-UX NFS 설정하기|작성자 대보름

posted by 외곈
2009. 5. 27. 21:29 Job/정리

패스워드 변경 방법

    Windows > java -classpath "%JEUS_HOME%\lib\system\jeus.jar" jeus.security.admin.Base64Coder  encode | decode <암호>
    Unix > java -classpath $JEUS_HOME/lib/system/jeus.jar jeus.security.admin.Base64Coder encode | decode <암호>
  encode 옵션 : 비밀번호를 암호화
  decode 옵션 : 암호화된 비밀번호를 해독

/jeus5/samples/quickstart/config/qs/security/SYSTEM_DOMAIN/accounts.xml

파일 안에

<name>administrator</name>
            <password>{base64}amV1cw==</password>

이부분의 amV1cw== 를 decode에 입력하면

복호화하여 비밀번호를 출력한다.

 

    예) C:\>java -classpath "%JEUS_HOME%\lib\system\jeus.jar" jeus.security.admin.Base64Coder  decode amV1cw==

posted by 외곈
2009. 5. 26. 16:10 Job/정리


* Split Partition

ALTER TABLE FW_DP_LDS_DEFAULT

SPLIT PARTITION P_20090109 AT ('20090106000000')

INTO (PARTITION P_20090105   TABLESPACE OASISDB_PILOT,

PARTITION P_20090109 TABLESPACE OASISDB_PILOT);


* Add Partition

ALTER TABLE FW_1DAY_LANE_DEFAULT

ADD PARTITION P_20090109

VALUES LESS THAN ('20090110')

TABLESPACE OASISDB_PILOT;

 

posted by 외곈
2009. 5. 12. 16:38 Job/정리

Oracle 세션(Session) 관리

 

오라클은 데이터베이스 접속이 이루어지면 세션을 시작한다.세션은 사용자가 데이터베이스에 연결되어 있는 동안 계속 유지된다.
세션이 시작되면 오라클은 해당 세션에 세션 ID(SID)를 할당한다. 사용자 세션을 출력하려면 v$session 뷰에 쿼리를 수행하면 된다.
v$session에서 각 세션은 고유한 SID(Session identifier)와 SERIAL#(serial number)를 갖는다.
시리얼 번호는 세션이 종료되었으나 다른 세션이 동일한 SID를 갖고 시작되었 때, 세션 명령들이 정확한 세션 객체에 적용될 수 있도

록 보장해준다.

 

v$session 뷰는 사용자 이름, 장치 이름, 프로그램 이름, 상캐 및 로그인 시각 등 세션에 대한 많은 유욯한 정보들을 갖고 있다.

 

(ex)
select username, program from v$session;


-> 어떤 사용자들이 DB에 접속하였고 어떤 프로그램들을 수행하고 있는지 확인하는 쿼리

 

 

세션 강제 종료

 

세션을 강제 종료해야할때는 alter system 명령어를 사용하는데, 사용자 세션을 강제 종료하기 위해서는 v$session 뷰의 SID와

SERIAL# 값이 필요하다.

 

상황 # 사용자 SUNNY에 의해 생성된 세션을 종료할때..

 

SQL> select username, sid, serial#, status
from v$session
where username = 'SUNNY';


USERNAME                SID         SERIAL#       STATUS
--------------------- -------------- -------------- ----------------
SUNNY                       10               3             INACTIVE


SQL> alter system kill session '10, 3';


System altered.


SQL> select username, sid, serial#, status
from v$session
where username = 'SUNNY';


USERNAME                SID         SERIAL#       STATUS
--------------------- -------------- -------------- ----------------
SUNNY                       10               3              KILLED


 

- 오라클이 세션을 강제 종료할 떄, 해당 세션은 더 이상의 SQL문을 실행하는 것을 막는다. 만일 강제 종료하는 시점에 SQL문을 실행

중이었다면, 해당 SQL문은 종료되고 모든 변경사항들은 롤백된다. 또한 해당 세션에 의해 사용되던 잠금(LOCK) 및 기타 자원들도 해

제된다.

 

 - 오라클이 INACTIVE 세션을 강제 종료하는 경우에는 세션을 종료시키고, 상태를 KILLED로 표시한다. 사용자가 계속하여 해당 세션을

사용하려고 시도하면 에러 메세지가 반환되며, 세션 정보는 v$session에서 제거된다.

 

 - ACTIVE 세션을 강제 종료하는 경우에는 오라클이 세션을 종료시키고, 해당 세션이 종료되었다는 에러 메시지를 사용자에게 즉시 발생 시킨다. 만일 오라클이 세션에 의해 사용되고 있던 자원을 60초 이내에 해제할 수 없을 때에는 해당 세션이 강제 종료될 것이라는

메시지를 사용자에게 발생시킨다. v$session 뷰의 상태는 다시 KILLED로 조회될 것이다.

 

- 만일 사용자가 현대 트랜잭션을 완료하고 사용 중이던 세션을 종료하려고 하면 DISCONNECT SESSION 옵션을 사용하면 된다.

 

alter system disconnect '10', '3' post_transation;

 

immediate 옵션과 사용하면 진행중이던 트랜잭션을 롤백하고 모든 세션의 잠금을 해제하며 전체 세션 상태를 복수한 후 사용자에게

즉시 제어 권한을 넘긴다.

 

alter system disconnect session '10', '3' immediate;
alter system kill session '10', '3' immediate;

 

 

+)

 

Q. SID는 세션식별자로 유니크한 값을 가지는데 SERIAL#값까지 갖는 이유는 무엇일까?

 

A. SID는 사용자별로 할당되는 값이 아니라 세션마다 할당되기 때문에 재사용됩니다. 만약 10, 12번 세션을 확인 후 KILL SESSION명령을 하기전에 10번 세션이 로그아웃을 하고 바로 다른 세션이 연결되어서 SID가 10번으로 할당되는 경우가 있다고 해봅시다. 이럴경우 SID만 가지고 세션을 KILL시키면 내가 원하는 세션이 아닌 다른 세션을 KILL 시키는 문제가 발생할 수 있습니다. 그래서 SERIAL#값을 하나 더 두어 세션을 구분하는 것입니다.

posted by 외곈
2009. 4. 16. 19:34 Job/정리

Adding Charts to Web-Based J2EE Applications

비지니스 어플리이션은 대체로 데이타를 다룬다. 따라서 개발자들은 종종 유저들이 그러한 데이타들을 분석할수 있도록 하는 컴포넌트를 제공해주어야 할 경우가 생기게된다. 이러한 경우 한가지방법은 텍스트베이스의 리포트를 제공해주는것이 있을수 있고, 다른방법으로는 그래피컬한 차트를 이용하여 데이타를 표현하여 그것을 제공해주는 방법이 있다.

차트는 대단히 유용한 툴인데, 유저들에게 시각적 데이타 요소들의 비교점을 제공해주고, 대량의 데이타를 다룰때 문자리포트로는 쉽게 구분되지않을수 있는 트렌드와 패턴을 쉽게 식별하여 줄수 있도록 한다. 오늘날 많은 비지니스 소프트웨어들이 웹베이스화되고 브라우져를 통해 전달되는 패턴을 취하고있는데, 그럼에도불구하고 이러한 어플리케이션에 대한 요구사항들, 특히 데이타분석에 대한 요구사항은 이전의 패턴을 그대로 따르고있다. 다행히도, 만약 당신이 J2EE 테크놀러지를 사용하여 개발을 진행한다면 몇몇 오픈소스 들이 도움을 줄 수 있다. 이 글이 J2EE 개발자들로 하여금 보다 빠르고, 시각적이며, 그래피컬한 차트를 업무에 활용할수 있도록 도움을 줄  수 있을 것이다.

 

JFreeChart and Cewolf—A Powerful Combination

 

JFree.org 는 많은 유용한 오픈소스 프로젝트를 진행하고 있는 웹사이트이다. JFreeChart는 그러한 프로젝트의 하나로 David Gilbert에 의해 주도되었다. JFreeChart는 데이타셋(a set of data)에 기초하여 시각적 그래픽차트를 형성하여주는 몇개의 자바 라이브러리로 구성되어있다..

Cewolf 는 또다른 오픈소스 프로젝트이다. Cewolf는 JSP태그컬렉션을 포함하는 고유한 몇개의 라이브러리 셋을 포함하고있다. Guido Laures에 의해 시작된 이 프로젝트는 개발자들이 JFreeChart기반에서 jsp페이지에 보다쉽게 차트를 표현하는 방법을 제공한다.즉 Cewolf는 JFreeChart를 기반으로 하여 그 위에 구성된 일종의 레이어인 셈이다. Cewolf는 JFreeChart로의 데이타 input을 지원하며, 결과 이미지를 jsp tag에 설정된 정의에 따라 브라우저에 구현한다. 이 두 프로젝트의 라이브러리들은 우리가 원하는 결과를 얻기위해 필요한것들이다. 가장 최근의 Cewolf버전은 version 0.9.8로 JFreeChart의 0.9.8버전을 지원하고 있다.(참고로 JFreeChart의 현재최신버전은 0.9.9이다)

 

 

Concepts and Terminology

그래피컬 차트는 하나이상의 데이타 '시리즈들'을 표현한다. 어떤경우에는 이러한 시리즈들은 하나이상의 '카테고리'들로 그룹화 되어지기도 한다. 시리즈는 간단히 말해 이름으로 구분된 데이타 값들의 집합이다. 예를들어 우리가 개인적으로 좋아하는 계절에 대한 투표를 한다고 가정하면 봄,여름,가을,겨울드이 시리즈명이 될수 있을것이다. 차트에서는 각각의 시리즈들은 유니크한 색이나 패턴으로 나타나며, 범례에 표시된다. 또한 시리즈들을 그룹화하여 카테고리로 나타내는것도 가능하다. 만약 우리가 전에 예로들었던 계절에 대한 투표가 2년에 걸쳐 진행되었다면 각각의 년도가 두 세트의 데이타 시리즈를 그룹화하는 카테고리가 될수 있을것이다. 마지막으로 각 년도에 대해 어떤 특정 방식의 차트(pie,line,bar and so forth)로 표현 할 것인가를 결정하는것은 어떻게 데이타를 표현하기를 원하느냐 하는것과, 보여지려는 데이타의 복잡성정도에 의해 결정된다.

차트는 많은 경우 데이타베이스를 이용하여 데이타를 표현한다. 따라서 JFreeChart는 소스가되는

데이타를 필요로 하는데, 이것들은 데이타셋(Dataset)이라 불리는 자바 인터페이스에 기초하여 정의된다. 두가지의 가장 일반적인 데이타셋은 카테고리데이타셋(CategoryDataset)과 파이데이타셋(PieDataset)이다. 알다시피 파이데이타셋은 파이차트를 표현하는데 필요한 데이타들을 제공한다.

파이차트는 차트중에 가장 간단한 타입이다. 파이차트는 데이타시리즈들의 값을 표현하며, 전체에 대해 어느정도의 비율을 나타내는지를 보여준다. 카테고리데이타셋은 하나이상의 카테고리에 의해 그룹화된 시리즈들을을 표현하는 보다 복잡한 데이타셋을 위한 인터페이스이다.

Cewolf는 데이타셋프로듀서(DatasetProducer)라고 불리는 인터페이스를 제공한다. 개발자들은 웹어플리케이션으로부터 JFreeChart로 데이타를 넘겨주기위해 이 인터페이스를 임플리먼트(implement)한다. JFreeChart데이타셋으로 리퀘스트데이타를 넘겨주는것은 데이타셋프로듀서의 역할로, 이로 인해서 차트가 구성되게 된다.

 

 

Getting Started

이번 장에서는 파이차트 구현을 위한 기술적 세부사항들에 초점을 맞추어 이야기를 진행해볼 것이다. 가장 처음 필요한것은 샘플데이타들이다. 이 예제를 위해 나는 employee와 dapartment테이블을 생성할것이다. 아래에 hsql 데이타베이스를 위한 쿼리가 있다.

 

CREATE TABLE dept (

dept_id INT NOT NULL IDENTITY, 
name VARCHAR(30) NOT NULL, 
descrip VARCHAR(200) 
); 
 
CREATE TABLE emp ( 
 emp_id INT NOT NULL IDENTITY, 
 dept_id INT NOT NULL, 
 f_name VARCHAR(30), 
 l_name VARCHAR(30), 
 hire_date DATE, 
CONSTRAINT fk_dept_id FOREIGN KEY (dept_id) 
REFERENCES dept (dept_id) 
); 
 
INSERT INTO dept (name,descrip) 
VALUES('IT', 'Information Technology'); 
INSERT INTO dept (name,descrip) 
VALUES('ACCT', 'Corporate Accounting'); 
INSERT INTO dept (name,descrip) 
VALUES('MRKT', 'Sales and Marketing'); 
INSERT INTO dept (name,descrip) 
VALUES('HR', 'Human Resources and Payroll'); 
INSERT INTO emp(dept_id,f_name,l_name,hire_date) 
VALUES(0,'Mike','Smith','2003-01-29'); 
INSERT INTO emp(dept_id,f_name,l_name,hire_date) 
VALUES(0,'Joe','Taylor','2003-04-15'); 
INSERT INTO emp(dept_id,f_name,l_name,hire_date) 
VALUES(0,'Jennifer','Betts','2003-05-07'); 

 

Employees는 네개의 departments중 하나에 소속될것이다.

각각의 employee의 고용일은 emp 테이블에 표시되어있다.

이곳( Here ) 전체 SQL 스크립트가 나타나있다. 만약 우리가 만든 차트와 데이타의 차이점을 알아보기 원한다면 스크립트를 다운받아 비교해보는것도 좋을것이다.

웹어플리케이션에서 당신은 몇개의 JFreeChart와 cewolf를 포함하는

라이브러리들을 포함시켜줄 필요가 있다.

이곳에서 다운받아 필요한 jar파일들을 사용할수 있다  Cewolf distribution

이 외에 추가적인 JFreeChart파일들을 다운받을 필요는없으며 이 jar파일들을

당신의 WEB-INF/lib 폴더에 복사하라

jfreechart-0.9.8-demo.jar Jfreechart-0.9.8.jar Jcommon-0.8.0.jar Commons-logging.jar Cewolf.jar
Batik-xml.jar Batik-util.jar Batik-syggen.jar Batik-dom.jar Batik-awt-util.jar

cewolf는 자바 서블릿 문법으로 작성되어, 차트를 렌더링하기위해 CewolfRenderer라는 서블릿이

존재한다. 이 서블릿은 두개의 입력 파라미터들을 가지고있는데, 이것들에 대해서는

아래서 이야기될것이다. 여기서는 이 서블릿들을 WEB-INF/web.xml에 매핑하는것을 우선

알아보겠다

 

 CewolfServlet 
de.laures.cewolf.CewolfRenderer 
<!-- sets storage implementation --> 
 
storage 
de.laures.cewolf.storage. TransientSessionStorage 
 
<!-- sets overlib.js location relative to webapp --> 
 
overliburl 
etc/overlib.js  
 
 
 
CewolfServlet 
/cewolf/* 
 

cewolf는 etc/ 디렉토리에 자바스크립트 파일을 포함하고있는데(overlib.js)

이것은 두개의 주요한 웹브라우져인 Internet Explorer and Mozilla에 대하여 툴팁을 렌더링하는데에 이용되는
스크립트들을 포함하고있다

Mozilla브라우저는 Explorer와는 약간 다른방식의 메카니즘을 사용하기때문에 이 스크립트 파일은 당신의
웹어플리케이션의 root폴더에 추가하도록
하자

Cewolf는 기본적으로 유저의 HttpSession object에 존재하는 모든 이미지들을 가지고 온다.
서블릿의
initialization 파라미터인 TransientSessionStorage
클래스가 이 역할을 하게된다.
다른 옵션으로는 시스템상의 이미지를 가지고오는
옵션이 존재하는데, 이것을 위해서는 storage의
param-value tag안에 있는

TransientSessionStorage를 같은 패키지의 FileStorage 클래스로

바꾸어주어야한다. 모든 차트 이미지는 PNG 타입의 이미지로 저장이된다

(물론 다른 타입도 가능하다) PNG파일은 대부분의 웹브라우저에서 지원되는

높은 품질의 이미지형식이다.

이제 당신의 어플리케이션 연동이 완료되었다

이제 당신은 데이타를 생성하고 표현하기위해 자바클래스와 jsp파일을

코딩하는것들이 필요하다. 우선 자바파일에 대해 생각해보면,

앞에서 언급되었듯이 Cewolf는 JFreeChart에 데이타를 제공하기위한

DatasetProducer 인터페이스를 정의하고 있다

아래에 DatasetProducer 인터페이스가 보여지고있다.

 

Object produceDataset(Map params)Method that returns the data (as a Dataset) for rendering. Typically, you would access your database here, either directly or indirectly, to provide this data.
boolean hasExpired(Map params, Date since)This method can be used to interrogate the last time the data was produced and determine whether produceData needs to be invoked again.
String getProducerId()Method that uniquely identifies a type of DatasetProducer.

produceDataset 메소드는 이 그룹의 가장주요한 메소드이다

이 메소드는 당신의 차트에 필요한 데이타들을 제공하는 메소드이기 때문이다

이 예제에서, 당신은 각 부서에 속한 employees의 인원수를

보여주는 간단한 파이차트를 생성할것이다. emp테이블과 dept테이블로부터

해당데이타를 가져오는 쿼리를 동작시켜 데이타베이스로부터 정보를 가져와

보도록 한다.

다음 코드를 보자 EmployeesByDept.java

보는것과 같이 이 코드는 DatasetProducer를 임플리멘테이션하고있다.

예제를 간단히 하기위해 hasExpired메소드의 리턴값을 false로 지정하자

이것은 데이타셋이 expire되지않는다는 의미이다.

실제 어플리케이션에서는 이부분을 로직에 따라 결정해주면될것이다

데이타베이스에 접근하는EmployeesByDept은 utility 클래스로부터

받아와 사용할수 있으며 파이차트의 생성을위해 임플리멘테이션된

DefaultPieDataset의 인스턴스를 리턴한다. 또한 쿼리는 입력 파라미터의

존재유무에 따라 실행여부가결정된다. 당신이 파라미터를 지정하는것을

잊지않았다면 쿼리는 다음과같이 실행될것이다

SELECT COUNT(emp_id), dept.name FROM emp, dept WHERE 
emp.dept_id = dept.dept_id; 
 

이상의 쿼리에 의해 JFreeChart가 생성되고 당신의 JSP파일이 요청할때

퀘스트에 의해 화면에 표시될것이다.

Cewolf 태그가 이것을 실행하기위해 어떻게 코드를 표현하는지

다음의 소스를 살펴보자 piechart.jsp

piechart.jsp에는 두개의 parent tag가 존재한다.

chart 와 img가 그것인데 차트 태그는 태그와,차트의랜더링, 차트의타이틀,

배경색등의 상세기능을 담당하는 어트리뷰트를 포함하며

차트 설정의 모든부분을 담당한다

차트태그에서 가장 중요한정보를 담고있는부분은 다음의 태그이다

  
 

data 태그는 차트를 랜더링하는데 필요한 데이타셋을 나타낸다

pieChartView는 페이지의 처음에서 선언한 EmployeesByDept의 인스턴스이다

 

그 바로아래에 있는 다른 parent 태그는 img태그이다

이 태그는 차트가 어떻게 표현될것인지를 결정한다.

이 태그는 높이,길이,테두리등의 그래픽요소를 컨트롤하는 attribute를

포함하고있다. 차트와 img태그는 서로 차트의 id 어트리뷰트와 img의 chartid태그를

통해 서로 링크되어 있다. 이번 예제에서 당신은 차트의 id를 pieExample이라고

주었는데, 이 태그정의들은 아래의 파이차트 이미지에서 다음과같이 보여진다

 

우리의 예제가 훌륭한 차트형식으로 표현되었다.

그러나 당신은 이 예제를 향상시킬수 있을것이다.

많은 차트들이 각각의 데이타 시리즈들을 표현하기위해 범례부분에 표시하는

텍스트를 포함하여 여러가지 다양한 텍스트들을 가지고 있다.

당신은 이미지 자체에 텍스트를 삽입할 수도 있고, JFreeChart와 Cewolf를

사용하여 텍스트들을 tool tip으로 나타낼수도 있다.

그럼 유저의 마우스가 특정 이미지상의 특정 시리즈들을 가르키는것에 따라

툴팁을 나오게 하는 방법에 대해 알아보자

이를위해서 당신은 generateToolTip메소드를 임플리멘테이션한

PieToolTipGenerator 타입의 인스턴스를 얻어야한다.

가장 쉬운방법은 EmployeesByDept.java의 이너클래스로 이를 추가하는것이다

여기(Here)에 업데이트된 자바파일의 소스가있다

다음의 코드들이 새로이 삽입되었다.

 

 /**Inner Class to generate tool tips for data.*/ 
PieToolTipGenerator pieTG = new PieToolTipGenerator()
 { public String generateToolTip(PieDataset dataset, 
Comparable section, int index) { 
return String.valueOf(dataset.getValue(index) + 
" employees total" ); } }; public PieToolTipGenerator 
getPieTG() { return this.pieTG; } 

 

다음은 새로이 향상된 차트를 표시하기위한 jsp파일이다 piechart.jsp

많은 향상이 된 두번째의 파이차트를 표현하고있다.

페이지의 윗부분에서 PieToolTipGenerator의 인스턴스를 얻고있다


<% pageContext.setAttribute("pieChartViewToolTips",
pieChartView.getPieTG()); %> 

 

추가적으로 툴팁을 사용하기위해 img태그에 tag와 map이 추가될 필요가있다

두번째 파이차트에 툴팁을 추가하면서, 나는 추가적인 기능들을 가진

태그들을 사용하였다. 차트이미지는 이제 pie3d 형식의 차트가 되었으며

차트의 범례는 차트로부터 따로따로 각각 생성된다.

보다중요한것은 이제 차트태그의 바로아래에 있는 producer태그를 이용하여

inputYeat라는 입력파라미터를 사용할 수 있게되었다는 것이다.

차트를 파라미터를 사용하여 표현하는것은 동적인 차트를 유저들에게 제공하는

데 있어 키가 되는 부분이다.

표준적인 어플리케이션에서 이러한 파라미터값들은 HTML 폼에서 유저들이 submit

한 값으로부터 입력될것이다.

<>name="year" value="<%=(Serializable)inputYear%>"/>

 

 

EmployeesByDept에서 당신은 입력파라미터를 체크해보아야한다.

만약 파라미터가 제공된다면 당신은 우리의 데이타를 년도별로 정렬할수 있을것이다

그림1은 두가지 파이차트를 보여준다

두번째차트가 HR employees를 나타내는 시리즈에 대해서 '6 employees total'

이라는 툴팁 텍스트를 표시하는것을 주목하라

아래에 범례가없는 3차원 파이 차트가 보여지고있다.

More Advanced Charts

보다 복잡한 차트는 한개이상의 카테고리를 포함하는 시리즈들의

데이타를 표현하기위해 쓰여진다. JFreeChart의

CategoryDataset 인터페이스는 카테고리에의해 그룹화된 데이타들을 포함하는

시리즈들을 구현하고 있다. 아래에 링크되어있는 두번째의

자바클래스파일을 살펴보자

EmployeesByDeptAndQtr.java

 

EmployeesByDeptAndQtr 역시 Cewolf의 DatasetProducer 인터페이스를

임플리멘테이션하고있다. 그 이름이 나타내는것처럼 이 클래스는  

각각의 department에 대한 head count의 수를 반환하는 데이타베이스

뭐리를 실행하고,quarter of the employee's hire date를 카테고리화

하기위해 작성된 클래스이다. 아래에 데이타베이스에 사용할 쿼리문이 나와있다


SELECT COUNT(emp_id), QUARTER(emp.hire_date) quarter,
 dept.name FROM emp, dept WHERE emp.dept_id = 
dept.dept_id GROUP BY dept.name,QUARTER(emp.hire_date); 

 

리턴되는 DefaultCategoryDataset로부터 당신은 몇가지의 차트타입을

생성할 수 있다. 각각의 이러한 차트들은 x,y축을 가지고있는데

x축은 데이타를 수평적으로 표현하고 y축은 수직적으로 표현한다.

사용되는 차트의 유형에 따라 하나의 플룻은 value points를 표현하고,

파이차트와 같은 다른 차트에서는 데이타 시리즈들은 여러색깔의

글과 색으로 표현되어진다(범례에 쓰이는것 포함)

당신은 세부분으로 나누어 그것을 표현할수있는데, 가로바와 세로바, 그리고

라인차트가 그것이다. 바차트는 x,y축의 깊이로 데이타를 표현하고,

라인차트는 각 데이타포인트를 라인으로 연결하여 차트를 가로지르는

방식으로 데이타를 표현한다.

다음의 내용을 살펴보자 categorychart.jsp

이 파일은 piechart.jsp에서 본것과 비슷한 패턴으로 작성되어있다.

DatasetProducer instance를 선언하고 JSP 태그세트를 이용하여

차트를 표현하고있다. 이 파일은 'horizontalBar3D', 'verticalBar3D',

'line'.의 3가지 차트방식의표현법을 보여주고있다

이 3가지 차트는 DatasetProducer에서 제공된 같은 CategoryDataset를

사용한다. 단 2개의 새로운 태그 어트리뷰트만이 사용되었다.

xaxislabel 과 yaxislabel이 그것이다.

다음에서 그것을 보여주고있다.



Figure 2. Various Category Charts

 

Conclusion

이 글의 목적은 JFreeChart와 Cewolf를 이용하여 그래픽 차트를 구현하는

것을 소개하는데에 있다. 나는 추가적인 차트타입과 향상된기능,옵션들을

살펴보기위해 각각의 웹사이트를 살펴보는것을 강력하게 추천한다.

JFreeChart 추가적인 기능문서들은 구매해야 사용이가능하다.

그러나 각 프로젝트들은 질의에 대한 답을 해주고 조언을 해줄수있는

커뮤니티 포럼들을 운영하고있으며, 온라인 Javadocs를 제공한다.

JFreeChart와 Cewolf의 컴파일로 J2EE 개발자들은

유용하고 사용하기편하며 사용자의 데이타분석요구를 만족시킬수있는

툴을 가지게 될것이다.

 

 

출처 : [직접 서술] 블로그 집필 - 민군네집

posted by 외곈
2009. 4. 2. 15:27 Job/정리

캐시 유형

설명

distributed scheme

노드 클러스터 전반에 데이터가 저장되어 있는 분산 캐시 정의

replicated scheme

모든 클러스터 노드 전반의 캐시 엔트리를 복제하는 캐시 정의

read-write-backing-map scheme

관계형 데이터와 같은 영구적인 캐시 저장소를 제공하는 맵 정의

external scheme

디스크와 같은 외장 캐시 정의

class scheme

java.util.Map 인터페이스의 구현을 요구하는 커스텀 캐시 구현 정의

posted by 외곈
2009. 2. 25. 00:50 Job

Oracle Coherence는 클러스터로 구성된 애플리케이션 데이터를 캐싱하는 방법을 혁신했습니다. Oracle Coherence는 마치 단일 애플리케이션 서버처럼 작동하는 클러스터형 애플리케이션과 애플리케이션 서버 내 데이터를 관리합니다. 데이터베이스 애플리케이션은 더 이상 데이터를 검색, 업데이트 또는 삭제해야 할 때마다 직접 데이터베이스에 쿼리할 필요가 없습니다.

하나의 Coherence cache 는 데이터베이스와 클라이언트 애플리케이션 간을 연결하는 매개체의 역할을 담당하는 데이터 객체의 집합입니다. 데이터베이스 데이터가 캐시에 로드되면 여러 다른 애플리케이션에서 이용할 수 있습니다. 따라서, Coherence cache는 데이터베이스의 부하를 줄이고 데이터베이스 데이터에 보다 신속하게 액세스할 수 있도록 합니다.

Coherence cache는 데이터베이스 분리와 데이터 복제를 통해 보다 높은 가용성을 실현합니다. 캐시에 대한 변경은 해당 데이터베이스가 가용 상태가 될 때마다 데이터베이스와 동기화될 수 있습니다. 데이터베이스 또는 애플리케이션 노드가 가용 상태가 아니라고 하더라도 Coherence cache에 의해 사용되는 지연 로드 및 지연 쓰기 메커니즘(lazy load and lazy write mechanism)과 Oracle Coherence가 제공하는 페일오버 및 페일백을 통해 데이터베이스 업데이트가 안정적으로 수행됩니다.

데이터 객체상에서 데이터 수정 작업이 수행될 수 있기 때문에 Coherence cache는 애플리케이션 서버의 클러스터 전반에서는 물론, 캐시 내 데이터 객체 전반에서도 분산 처리됩니다.

Oracle Coherence는 또한 이벤트 기반 처리 기능을 제공합니다. 캐시 내 데이터 객체의 상태는 모니터링되며 여러 실행 조치를 통해 BPEL 프로세스 시작과 같은 여타 프로세스를 호출할 수 있습니다.

Oracle Coherence는 여러 다양한 유형의 캐시를 지원합니다. replicated 캐시에서 데이터는 클러스터 내 각 애플리케이션 서버 노드에 복제됩니다. 이는 보다 고속 읽기 액세스가 요구되는 경우에 적합하지만, 쓰기 액세스에는 적합하지 않습니다. 그 이유는 각 노드에 대해 데이터 쓰기 작업이 수행되기 때문입니다. distributed (분할된) 캐시에서 데이터는 여러 다른 노드 전반으로 분산(로드 밸런싱)됩니다. 페일오버는 백업을 이용하여 분산 캐시 전반에서 구현되며 이는 또한 클러스터 노드 전반으로 분산됩니다.

Oracle Coherence는 Cluster 서비스, Distributed Cache 서비스 및 Replicated Cache 서비스와 같은 서비스를 통해 구현됩니다. 어떤 캐시 유형이 사용되건 간에 애플리케이션은 동일한 API를 통해 데이터에 액세스하고 이를 저장합니다.

캐시 구성 구축 설명자(cache configuration deployment descriptor)는 캐시를 구성하는 데 사용됩니다. cache configuration 파일의 최상위 요소(root element)는 cache-config입니다. 캐시 이름과 이름 패턴은 subelement cache-mapping를 이용하여 caching-scheme-mapping 내 캐시 유형에 대응됩니다. 캐시 유형은 caching-schemes 요소 내에서 정의됩니다. 널리 사용되고 있는 대표적인 캐시 유형은 아래 표에 열거되어 있습니다.

표 1. 캐시 유형

캐시 유형

설명

distributed scheme

노드 클러스터 전반에 데이터가 저장되어 있는 분산 캐시 정의

replicated scheme

모든 클러스터 노드 전반의 캐시 엔트리를 복제하는 캐시 정의

read-write-backing-map scheme

관계형 데이터와 같은 영구적인 캐시 저장소를 제공하는 맵 정의

external scheme

디스크와 같은 외장 캐시 정의

class scheme

java.util.Map 인터페이스의 구현을 요구하는 커스텀 캐시 구현 정의


이제 본격적으로 Oracle Jdeveloper를 이용하여 Coherence cache를 작성하고 구성하는 실습 과정을 시작하겠습니다.

 

필수 전제 조건

Oracle Coherence 3.3.1 (전체 설치 절차는 설명서 참조)
Oracle Database
Oracle JDeveloper 11g (본 아티클 작성 시 Technical Preview 내)

 

프로젝트 구성

Oracle Coherence Version 3.3.1 - Pure Java를 다운로드하고 zip 파일을 디렉토리로 추출합니다.
Coherecne를 다운로드하고 zip 파일을 디렉토리로 추출한 다음, Oracle Jdeveloper 내에서 애플리케이션 및 프로젝트를 생성합니다. 프로젝트에 Java class, CoherenceCache.java를 추가합니다. coherence cache는 해당 Java class 내에 생성될 것입니다. XML 문서, cache-config.xml을 캐시 구성 구축 설명자로서 추가합니다.

프로젝트 라이브러리에 Coherence JAR 파일인 coherence.jar와 tangosol.jar를 추가합니다. Coherence JAR 파일은 Oracle Coherence 설치 시 \coherence\libation 디렉토리 내에 위치합니다. Oracle JDBC 라이브러리를 추가합니다. 이는 프로젝트 라이브러리에 데이터베이스가 액세스할 수 있도록 하는 데 필요합니다.

 

Run Configuration

다음으로, 해당 애플리케이션을 위한 Run configuration을 수정하여 cache configuration 파일을 runtime Java 옵션으로 추가합니다. 프로젝트 노드를 선택하고 Tools -> Project Properties를 선택합니다. Project Properties 창에서 Run/Debug/Profile을선택합니다. Run Configuration Default가 기본으로 선택됩니다. Default configuration을 위해 Edit를 클릭합니다.

Edit Run Configuration 창 내에서 Launch Settings을선택합니다. Java Options 필드에서 다음과 같이 cache configuration 파일(cache-config.xml)을 지정합니다.

-Dtangosol.coherence.cacheconfig=[path-to-cache-config-file]/cache-config.xml

우리가 작성한 Oracle Coherence 애플리케이션의 경우, Java Options 필드 내에서 다음과 같이 지정하고(path to cache-config.xml는 다를 수 있음) OK를 클릭합니다.

-Dtangosol.coherence.cacheconfig=C:/Users/dvohra09/Documents/Jdeveloper/mywork/CoherenceCache/Coherence/cache-config.xml



Project Properties -> Run/Debug/Profile
창에서 OK를 클릭합니다. cache configuration 파일은 coherence Java 애플리케이션에 runtime Java 옵션으로서 추가됩니다

 

Cache Configuration

cache configuration 파일에서 caching-scheme-mapping 요소 내 cache-mapping 요소로 캐시 이름과 네이밍 패턴을 위한 매핑을 정의합니다. cache type default-replicated에 기본 매핑을 지정하고 캐시 이름 VirtualCache을 cache type default-distributed에 매핑합니다. DistributedCache 서비스를 이용하는 distributed-scheme 요소로 distributed caching scheme를 정의합니다. 아래에 열거된 cache configuration 파일은 Oracle Jdeveloper 내 cache-config.틔 파일에 복사됩니다.

                    
              VirtualCache
              default-distributed
         

     

     
         
         
              default-distributed
              DistributedCache
             
                 
                      default-backing-map
                 

             

         

   
              default-backing-map
              com.tangosol.util.SafeHashMap
              

   
캐시 애플리케이션

 

 

다음으로 Java 클래스 내에 캐시를 생성합니다. CacheFactory 클래스와 NamedCache 인터페이스를 가져옵니다.

import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;

캐시 인스턴스가 CacheFactory 클래스에서 생성됩니다. CacheFactory 클래스의 getCache() 메소드를 이용하여 NamedCache를 만듭니다. 캐시 이름VirtualCache을 이용하며 이는 distributed caching scheme로 매핑됩니다.

Named cache = CacheFactory.getCache ( "VirtualCache");

NamedCache는 클러스터 내 노드 전반에 공유된 자원을 보유하고 있는 java.util.Map입니다. put() 메소드를 이용하여 캐시 엔트리를 추가합니다.

cache.put (key, "Hello Cache");

캐시 엔트리는 get() 메소드를 이용하여 검색될 수 있습니다.

System.out.println((String)cache.get("hello"));

Oracle Jdeveloper 내 CoherenceCache 애플리케이션을 아래에 나열된 Java 클래스를 복사합니다.

package coherence;
 
import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
 
public class CoherenceCache {
       NamedCache cache;
 
       public CoherenceCache() {
       }
 
       public void putCache() {
             cache = CacheFactory.getCache("VirtualCache");
             String key = "hello";
             cache.put(key, "Hello Cache");
       }
 
       public void retrieveCache() {
             System.out.println((String) cache.get("hello"));
       }
 
       public static void main(String[] args) {
             CoherenceCache cache = new CoherenceCache();
             cache.putCache();
             cache.retrieveCache();
       }
}
Oracle Coherence 애플리케이션에서 오른쪽 버튼을 클릭하고 Run을 선택합니다. 



Oracle Coherence 애플리케이션이 실행되고 결과물이 Log 창에 표시됩니다. 이 결과물은 운영 구성(operational configuration)이 tangosol-coherence.xml에서 로드되고, 캐시 구성(cache configuration)이 cache-config.xml에서 로드되며 DistributedCache 서비스가 클러스터에 조인되는 것을 보여줍니다. 운영 구축 설명자인 tangosol-coherence.xml는 자체 클러스터링, 통신 및 데이터 관리 서비스를 위해 사용되는 운영 및 런타임 설정을 지정합니다.



Oracle Database Cache 생성

이 섹션에서는 Oracle Database로 지원되는 캐시인 Oracle Database 캐시를 작성하게 됩니다. 먼저 아래 SQL 스크립트로 Oracle Database 테이블을 만듭니다.

CREATE TABLE OE.CATALOG(id VARCHAR(25)
PRIMARY KEY, value VARCHAR(96));
INSERT INTO OE.CATALOG VALUES('catalog1', 'Tuning Undo Tablespace');
INSERT INTO OE.CATALOG VALUES('catalog2', 'Tuning Your View Objects');

Oracle Jdeveloper 내에서 해당 데이터베이스 캐시를 위한 Java 클래스인 DatabaseCache.java를 만들고 메소드 createCache(), addEntry(), retrieveEntry(), eraseEntry(), 및 queryCache()를 추가합니다.

 

커스텀 CacheStore

캐시를 백엔드 데이터베이스에 연결하기 위해서는 cache configuration 파일(cache-config.xml)요소인 cachestore-scheme이 필요합니다. cachestore-scheme 요소는 com.tangosol.net.cache.CacheLoader 또는 com.tangosol.net.cache.CacheStore 인터페이스를 구현한 커스텀 클래스로 구성되어야 합니다. CacheStore 인터페이스를 구현한 커스텀 클래스는 아래 나열되어 있습니다.

package coherence;

 

import com.tangosol.net.cache.CacheStore;

import com.tangosol.util.Base;

import java.sql.DriverManager;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.Collection;

import java.util.Iterator;

import java.util.LinkedList;

import java.util.List;

import java.util.Map;

 

public class DBCacheStore extends Base implements CacheStore {

 

       public DBCacheStore(String sTableName) {

             m_sTableName = sTableName;

             configureConnection();

       }

 

       protected void configureConnection() {

             try {

                    Class.forName("oracle.jdbc.OracleDriver");

                    m_con = DriverManager.getConnection(DB_URL, DB_USERNAME,

                                 DB_PASSWORD);

                    m_con.setAutoCommit(true);

             } catch (Exception e) {

                    throw ensureRuntimeException(e, "Connection failed");

             }

       }

 

       public String getTableName() {

             return m_sTableName;

       }

 

       public Connection getConnection() {

             return m_con;

       }

 

       public Object load(Object oKey) {

             Object oValue = null;

             Connection con = getConnection();

             String sSQL = "SELECT id, value FROM " + getTableName()

                           + " WHERE id = ?";

             try {

                    PreparedStatement stmt = con.prepareStatement(sSQL);

                    stmt.setString(1, String.valueOf(oKey));

                    ResultSet rslt = stmt.executeQuery();

                    if (rslt.next()) {

                           oValue = rslt.getString(2);

                           if (rslt.next()) {

                                 throw new SQLException("Not a unique key: " + oKey);

                           }

                    }

                    stmt.close();

             } catch (SQLException e) {

                    throw ensureRuntimeException(e, "Load failed: key=" + oKey);

             }

             return oValue;

       }

 

       public void store(Object oKey, Object oValue) {

             Connection con = getConnection();

             String sTable = getTableName();

             String sSQL;

 

             if (load(oKey) != null) {

 

                    sSQL = "UPDATE " + sTable + " SET value = ? where id = ?";

             } else {

 

                    sSQL = "INSERT INTO " + sTable + " (value, id) VALUES (?,?)";

             }

             try {

                    PreparedStatement stmt = con.prepareStatement(sSQL);

                    int i = 0;

                    stmt.setString(++i, String.valueOf(oValue));

                    stmt.setString(++i, String.valueOf(oKey));

                    stmt.executeUpdate();

                    stmt.close();

             } catch (SQLException e) {

                    throw ensureRuntimeException(e, "Store failed: key=" + oKey);

             }

       }

 

       public void erase(Object oKey) {

             Connection con = getConnection();

             String sSQL = "DELETE FROM " + getTableName() + " WHERE id=?";

             try {

                    PreparedStatement stmt = con.prepareStatement(sSQL);

                    stmt.setString(1, String.valueOf(oKey));

                    stmt.executeUpdate();

                    stmt.close();

             } catch (SQLException e) {

                    throw ensureRuntimeException(e, "Erase failed: key=" + oKey);

             }

       }

 

       public void eraseAll(Collection colKeys) {

             throw new UnsupportedOperationException();

       }

 

       public Map loadAll(Collection colKeys) {

             throw new UnsupportedOperationException();

       }

 

       public void storeAll(Map mapEntries) {

             throw new UnsupportedOperationException();

       }

 

       public Iterator keys() {

             Connection con = getConnection();

             String sSQL = "SELECT id FROM " + getTableName();

             List list = new LinkedList();

 

             try {

                    PreparedStatement stmt = con.prepareStatement(sSQL);

                    ResultSet rslt = stmt.executeQuery();

                    while (rslt.next()) {

                           Object oKey = rslt.getString(1);

                           list.add(oKey);

                    }

                    stmt.close();

             } catch (SQLException e) {

                    throw ensureRuntimeException(e, "Iterator failed");

             }

             return list.iterator();

       }

 

       protected Connection m_con;

       protected String m_sTableName;

       private static final String DB_DRIVER = "oracle.jdbc.OracleDriver";

 

       private static final String DB_URL = "jdbc:oracle:thin:@localhost:1521:ORCL";

       private static final String DB_USERNAME = "OE";

       private static final String DB_PASSWORD = "pw";

}


Oracle JDeveloper 내에 Java 클래스 DBCacheStore를 만들고 DBCacheStore.java listing을 Oracle Jdeveloper로 복사합니다. DBCacheStore 애플리케이션은 JDBC를 사용하여 Oracle Database에 액세스하지만 Hibernate 또는 JDO와 같은 다른 메커니즘은 사용되지 않을 수도 있습니다.

이제 데이터베이스 캐시를 위한 cache configuration 파일을 만들어 보겠습니다. 캐시 이름 패턴인 DBBacked*를 정의합니다. 이는 distributed caching scheme인 distributed-db-backed으로 매핑됩니다. CacheStore를 구현한 class coherence.DBCacheStore를 이용하여 distributed scheme 내에 cachestore scheme을 지정합니다. 캐시의 백엔드에 위치한 데이터베이스 테이블을 위한 init 매개변수는 DBCacheStore 클래스로 지정되어야 합니다. 테이블 이름은 init-param 요소 내에서 지정됩니다. DBCacheStore 클래스는 캐시 엔트리의 읽기 및 쓰기와 같은 데이터베이스 작업을 실행합니다. Coherence는 read-write-backing-map scheme이 사용되는 데이터소스의 읽기-쓰기(read-write) 캐싱을 지원합니다. read-write-backing-map scheme는 영구적인 저장소의 크기가 제한된 캐시를 제공하는 backing map을 정의합니다. Oracle Coherence는 다음과 같은 4가지 유형의 읽기-쓰기 캐싱을 지원합니다.

  • Read-Through – 애플리케이션에서 요구되거나 애플리케이션에서 이용할 수 있게 되는 경우, 캐시 엔트리를 데이터베이스에서 캐시로 읽습니다.
  • Write-Through – 캐시 엔트리에 대한 업데이터는 지연 없이 데이터베이스와 동기화됩니다.
  • Refresh-Ahead – 캐시 엔트리가 주기적으로 새로 고침을 실행합니다.
  • Write-Behind – 캐시에 대한 업데이트는 cache configuration 파일 내 write-delay-seconds 요소에 지정된 지연 시간 이후 비동기적으로 데이터베이스에 기록됩니다.

이제 여러분은 Write-Through 메커니즘을 사용하게 될 것입니다. 아래에 나열된 데이터베이스 캐시를 위한 cache configuration 파일을 Oracle Jdeveloper 내 cache-config.xml 파일로 복사하십시오.


 
  
  
   DBBacked*
   distributed-db-backed
  
 
 
  
  
   distributed-db-backed
   DistributedCache
   
    
     
      
       com.tangosol.util.ObservableHashMap
      
     
     
      
       coherence.DBCacheStore
       
        
         java.lang.String
         CATALOG
        
       
      
     
     false
     
     0
    
   
   
   true
  
 

 

캐시 엔트리 추가하기

DatabaseCache.java application addEntry() 메소드 내에서 CacheFactory 클래스의 getCache() 메소드를 이용하여 NamedCacheobject를 생성합니다.

NamedCache cache = CacheFactory.getCache("DBBackedCache");

DBBackedCache는 캐시 패턴인 DBBacked*와 일치하며 따라서 cache-config.xml 파일 내 distributed caching scheme인 distributed-db-backed로 매핑됩니다. NamedCache 객체의 put() 메소드를 이용하여 캐시 엔트리를 추가합니다.

cache.put(new String("catalog3"), new String("Evolving Grid Management"));

Write-Through 메커니즘이 사용되는 경우, 새로운 캐시 엔터리는 데이터베이스와 동기화되며 새 열은CATALOG 테이블에 추가됩니다. createCache()와 addEntry() 메소드를 제외한 모든 메소드를 Comment out 합니다. Oracle JDeveloper 내 DatabaseCache.java 애플리케이션에서 오른 쪽 버튼을 클릭하고 Run을 선택해 새 캐시 엔트리를 추가합니다.

put() 메소드가 호출되면 JDBC를 이용하여 새 캐시 엔트리를 데이터베이스 테이블 CATALOG로 매핑하는 store() 메소드가 DBCacheStore 클래스 내에 호출됩니다. Oracle Coherence 애플리케이션의 결과물이 Log 창 내에 표시되고 새 캐시 엔트리가 추가됩니다. 그 결과물은 운영 구성 구축 설명자(operational configuration deployment descriptor)와 캐시 구성이 로드되고 새 클러스터가 생성되며 DistributedCache 서비스가 클러스터에 조인하는 것을 보여줍니다.

Write-Through 캐시를 사용하고 있기 때문에 데이터베이스 테이블이 업데이트되었습니다.

새 캐시 엔트리는 NamedCache 객체의 remove() 메소드로 제거될 수 있습니다.

cache.remove(new String("catalog3"));

캐시 엔트리의 벌크 업로드는 putAll() 메소드를 이용하여 실행될 수 있습니다.

 

캐시 엔트리의 검색

캐시 엔트리는 NamedCache 객체의 get() 메소드를 이용하여 검색할 수 있습니다. 예를 들어 id catalog1를 위한 캐시 엔트리를 검색해 보겠습니다.

System.out.println((String) cache.get("catalog1"));

get() 메소드가 호출되면 JDBC를 이용하여 데이터베이스 테이블 데이터를 검색하는 load() 메소드가 DBCacheStore 클래스 내에 호출됩니다. Oracle Jdeveloper 내 캐시 엔트리를 검색하도록 comment되지 않은 createCache()와 retrieveEntry() 메소드를 포함한 Oracle Coherence 애플리케이션을 실행하는 데 따른 결과물은 아래와 같습니다.

벌크 검색은 NamedCache 객체의 getAll() 메소드를 사용하여 실행될 수 있습니다.

 

데이터베이스 캐시 쿼리

Oracle Coherence는 필터를 이용한 검색 기준을 토대로 캐시 엔트리에 대한 검색을 지원합니다. Coherence 필터는 com.tangosol.util.filter 패키지에서 제공되고 있습니다. Oracle Coherence Enterprise Edition 및 Grid Edition에서 색인은 Coherence cache에 추가되어 성능을 향상시킬 수 있습니다. 우리는 캐시 엔트리와 특정 패턴을 일치시키는 LikeFilter filter를 이용하여 데이터베이스 캐시에 대한 쿼리를 실행할 것입니다.

데이터베이스 캐시에 대한 쿼리를 실행하기 위해서는 쿼리에 앞서 캐시 엔트리를 생성해야 합니다. 캐시 엔터리는 필터를 이용한 쿼리가 실행되기 전에 get() 또는 getAll() 메소드를 이용하여 캐시에 대한 검색을 수행해야 합니다. 이를 위해 thegetAll() 메소드를 이용하여 데이터베이스를 검색하고 캐시 엔트리의 집합을 만듭니다.

HashSet hashSet=new HashSet();
hashSet.add(new String("catalog1"));
hashSet.add(new String("catalog2"));
hashSet.add(new String("catalog3"));
Map map=cache.getAll(hashSet);

“Tuning”을 시작으로 캐시 엔터리를 검색하는 LikeFilter 필터를 만들어 보겠습니다.

Filter filter = new LikeFilter(IdentityExtractor.INSTANCE, "Tuning%", '\\', true);

LikeFilter 필터를 포함한 entrySet() 메소드를 이용하여 데이터베이스 캐시에 대한 쿼리를 실행합니다.

Set results = cache.entrySet(filter);

쿼리 결과에 대한 반복 실행을 통해 검색된 캐시 엔트리를 산출합니다.

for (Iterator i = results.iterator(); i.hasNext();)
{
Map.Entry e = (Map.Entry) i.next();
System.out.println("Catalog ID: "+e.getKey() + ", Title: "+e.getValue());
}

데이터베이스 캐시 쿼리를 실행하기 위해 uncommented된 createCache() 및 queryCache() 메소드만을 가진 DatabaseCache.java 애플리케이션에서 오른쪽 버튼을 클릭하여 Run을 선택합니다 . 패턴 “Tuning%”과 일치하는 캐시 엔트리가 검색되고 Log 창 내에 출력됩니다.

Oracle Coherence는 ContinuousQueryCache 클래스를 이용하여 지속 쿼리를 지원합니다. 지속 쿼리(continuous query)는 지속 쿼리 캐시(continuous query cache)를 이용하여 최신 상태를 유지하는 쿼리입니다. 지속 쿼리 캐시에서는 쿼리의 결과가 변경될 수 있는 이벤트가 발생하는 경우, 이벤트 리스너(event listeners)를 사용하여 쿼리 결과를 업데이터합니다.

NamedCache 객체와 LikeFilter 객체를 사용하여 ContinuousQueryCache 객체를 만듭니다

ContinuousQueryCache queryCache = new ContinuousQueryCache(cache, filter );

이제 entrySet() 메소드를 사용하는 결과 집합이 생성되었습니다.

Set results = queryCache.entrySet(filter);

지속 쿼리 캐시를 이용하여 데이터베이스 캐시 일관성 애플리케이션을 실행합니다. 결과물은 지속적이지 않은 캐시의 결과물과 동일합니다. 그러나 캐시 엔트리가 업데이트되면 지속 쿼리 결과도 업데이트됩니다.

데이터베이스 캐시 애플리케이션인 DatabaseCache.java는 다음과 같습니다.

package coherence;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
import com.tangosol.net.cache.ContinuousQueryCache;
import com.tangosol.util.Filter;
import com.tangosol.util.extractor.IdentityExtractor;
import com.tangosol.util.filter.LikeFilter;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class DatabaseCache {
    NamedCache cache;
    public DatabaseCache() {
    }
    public void createCache() {
         cache = CacheFactory.getCache("DBBackedCache");
        
    }
    public void addEntry() {
    
    cache.put(new String("catalog3"), new String("Evolving Grid Management"));
   
    }
    public void retrieveEntry() {
    System.out.println((String) cache.get( "catalog1"));
    }
    public void eraseEntry() {
    cache.remove(new String("catalog3"));
    }
    public void queryCache() {
        Filter filter = new LikeFilter(IdentityExtractor.INSTANCE, "Tuning%", '\\', true);
        HashSet hashSet=new HashSet();
        hashSet.add(new String("catalog1"));
        hashSet.add(new String("catalog2"));
        hashSet.add(new String("catalog3"));
        Map map=cache.getAll(hashSet);
        ContinuousQueryCache queryCache = new ContinuousQueryCache(cache, filter);
        Set results = queryCache.entrySet(filter);
       /* Set results = cache.entrySet(filter);*/
        if(results.isEmpty())
        System.out.println("Result Set Empty");
            for (Iterator i = results.iterator(); i.hasNext();)
                {
                Map.Entry e = (Map.Entry) i.next();
                System.out.println("Catalog ID: "+e.getKey() + ", Title: "+e.getValue());
                }
    }
    
    
    public static void main(String[] args) {
        DatabaseCache databaseCache = new DatabaseCache();
        databaseCache.createCache();
       /*databaseCache.addEntry();
        databaseCache.retrieveEntry();
        databaseCache.eraseEntry();*/
        databaseCache.queryCache();
    }
}
posted by 외곈