블로그 이미지
외곈

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 29 30 31
  • total
  • today
  • yesterday
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 외곈
2009. 2. 14. 17:10 하고싶은말

옴니아 테마는 PDA까페에 올라온 것을 글씨랑 아이콘만 쪼금(..) 바꾸고...

S2U2 화면은 직접 만들었는데... 시간이 이렇게 오래걸릴줄은 생각도 못했다...-_-;;

사실 S2U2화면도 이미 만들어져있는거 이미지만 갈아친건데도...시간 꽤 걸리네..

나름 만족....

posted by 외곈
2009. 2. 8. 17:20 하고싶은말

평소에 옴니아폰에 투명 플라스틱 하드케이스를 덮어 사용했는데, 주로 모아키를 사용하던 지라 플라스틱케이스가

액정 끝부분을 덮어버리는 바람에 사용에 불편함이 많았다.


사진 처럼 '거' 혹은 '마' 이런 글을 쓰려면 'ㄱ' 을 누른상태로 왼쪽으로 슬라이드. 마 를 쓸때는 'ㅁ'을 누른상태로 오른쪽으로

슬라이드를 해주면 되는데 회색부분이 플라스틱 케이스가 씌워져있는 부분이라 안쪽으로 슬라이드를 할때는 지장이 없는데

바깥으로 슬라이드를 해주려 할때는 케이스에 걸려서 무척 힘이든다.

고민하던 차에 결국은 케이스 대신 필름을 씌우자고 마음을 먹었다.

신도림 셀피쉬가 꽤 유명하다고 하여 회사 워크샵 끝나고 집에 오기전에 잠시 들렸다.

테크노마트 9층에 가자마자 엄청난 호객행위를 간신히 뚫고 도착.(이거 생각보다 힘들다...)

헐..그런데 생각했던거보다 굉장히 허름했다.. 점포가 맞나 싶을정도로 매우 심플한 사무실 구조 와 배치..

아무튼 도착하니 여학생 둘이 아르고폰과 캔유에 붙이러 왔나보다.

직원분이 어떻게 붙이나 지켜봤는데...정말 고수의 손길이라는걸 느낄정도로 잘붙인다.

아무튼 예약을 안하고 오면은 기다려야 한다고 해서 기다리는데..

예약 안하고 온걸 엄청 후회했다... 끊임없이 밀려오는 예약손님들..

결국은 2시간 가까이 기다려서..겨우 붙였다.

나도 참..대단하다. 2시간이나 기다리고..그런데 붙이는걸 보고있으면 정말 시간가는줄 모를정도로 잘붙이고

또, 굉장히 스피디 하게 붙인다. 망설임 같은건 전혀 없이 한번에 샥샥..

결국 내 차례가 되서 인크레더블 실드를 붙였는데 굉장히 만족스럽다.

느낌은 뭐랄까...쫀득쫀득(?)한 느낌이 들긴하는데 책상 유리 위에 올려놓으면 찰싹 달라붙는다..

가격은 부착료까지해서 25500원. 카드결재가 안된다고 얘기는 들었는데 혹시나 해서 내밀었더니 해주더라..

하루정도지나니 기포도 다 빠지고 감촉도 많이 좋아졌다.

아이팟이나 PSP도 가져가서 붙여봐야겠다.
posted by 외곈