01.JAVA/Java2008. 11. 12. 17:13
반응형

기고인 : JCO 기술젼략팀장 김홍회(자바스터디 네트워크 대표 운영자)

Database 시장은 오라클, DB2, MS-SQL, MySQL등 많은 경쟁업체들의 각축장이 되어 왔다. BEA를 인수한 오라클은 점차 그 범위를 확장해 가고 있으며 Sun은 MySQL을 인수하며 시장에 합류하였다. 이렇듯이 Dabase는 Database가 시장에 갖는 의미만큼 각 업체에서 사활을 건 싸움을 하고 있다. 그리고 이러한 경쟁 시장에 JavaDB가 도전장을 내밀게 되었다. JavaDB는 제목처럼 경량화 DB를 모토로 만들어 졌으며 이 글은 소개 및 설치하는 방법과 실행 예제 등 기본적인 정보만 다루도록 하겠다.

1. JavaDB의 등장과 기원

여기서 필자는 JavaDB의 등장과 함께 기원이라는 단어를 사용했다. 그럼 JavaDB는 부모가 있다는 것인가? 그렇다. JavaDB의 기원은 1996년으로 거슬러 올라간다. IBM이 Cloudscape라는 프로젝트를 시작 하였으며 1999년에 Informix, 2001년에는 IBM에서 관리 하였으며 2004년에 지금의 Apache에 기부 되었다. Apache는 Apache Derby라는 프로젝트로 오픈 소스 프로젝트를 진행하고 있으며 Apache Derby는 Apache DB subproject라는 이름 또한 가지고 있다. 기존 Database가 무겁고 비싼 것에 비해 Derby는 경량화와 무료 라이센스 그리고 무엇보다 매력적인 오픈 소스를 표방하며 만들어 졌다. 이 프로젝트를 Sun에서 JavaDB라는 이름으로 JavaSE6에 포함시키며 공급하기 시작했다.

2. JavaDB의 특징

JavaDB의 특징은 Apache Derby의 특징과 같다. 이는 기존 Dababase와 성격이 매우 다른데 특징은 다음과 같다.

1) base engine과 JDBC driver 모두 합쳐 2메가바이트
2) 자바와 JDBC, SQL을 기초로 만들어짐
3) client/server 모드를 Derby Network Client JDBC driver and Derby Network Server. 를 통해 지원 가능
4) 설치 및 디플로이, 사용이 편함

또한 JavaDB는 다음과 같은 환경에 적합하다고 소개되어 있다.

1) 자바 애플리케이션 개발 및 테스트 : 사용하기 쉬우며 사용자의 컴퓨터나 메인프레임에서도 잘 돌아감.
아파치 라이센스하에 무료임.
2) 임베디드 애플리케이션
3) 멀티 플랫폼 환경 : 100% 자바이므로 Java DB에서 다른 오픈 스탠더드 데이터베이스로 마이그레이트 가능함.
4) Web 2.0 기반의 브라우져 based 환경
5) PDA와 같이 J2ME CDC에서 돌아가는 애플리케이션

먼저 base engine과 JDBC driver를 모두 합쳐서 2메가바이트라는 획기적이고도 믿을 수 없는 용량을 자랑한다.
또한 이전에 설명했듯이 Pure Java로 만들어 졌으며 설치법 또한 간단하다.

3. JavaDB 설치

JavaDB는 SE6를 설치하면 자동으로 설치되나 수동으로 설치하는 방법도 있다.

(1) homepage(http://developers.sun.com/javadb/downloads/index.jsp)에 접속하여 다운로드 하기
(2) 설치하기

① 윈도우의 경우

     javadb_<version>.ms를 더블 클릭하거나 msiexec /i javadb_<version>.msi 명령 실행

② 솔라리스의 경우
    1) 다운로드 하기
       javadb-<version>-solaris-<arch>-pkg.sh
    2) 권한 확인하기
       
chmod +x javadb-<version>-solaris-<arch>-pkg.sh

    3) 압축풀기
       
./javadb-<version>-solaris-<arch>-pkg.sh

    이 명령을 실행하고 나면 javadb-<version> 디렉토리 밑에 여러 개의 다음의 SVR4 package 디렉토리들이 생성된다

SUNWjavadb-common
SUNWjavadb-client
SUNWjavadb-core
SUNWjavadb-demo
SUNWjavadb-docs
SUNWjavadb-javadoc
SUNWjavadb-service

      4) su – root등을 사용하여 수퍼 권한자로 변경하기
      5) 기존 JavaDB 삭제하기
         기존에 JavaDB가 설치되어 있다면(디폴트 설치 경로는 /opt/SUNWjavadb 이다) 새 버전을 설치하기 전에 제거해야 한다. 현재 돌아가고 있는 패키지를 보는 방법은 다음과 같다.
    
pkginfo | grep SUNQjavadb-

          기존 패키지를 제거하기          
        
pkgrm SUNWjavadb-client SUNWjavadb-core SUNWjavadb-demo SUNWjavadb-docs SUNWjavadb-javadoc SUNWjavadb-service SUNWjavadb-common

      6) 설치하기
        
cd javadb-<version>
pkgadd
-d . SUNWjavadb-common SUNWjavadb-client SUNWjavadb-core SUNWjavadb-demo SUNWjavadb-docs SUNWjavadb-javadoc SUNWjavadb-service

      7) 새 JavaDB 패키지 설치하기
         
cd javadb-<version>
          pkgadd
-d . SUNWjavadb-common SUNWjavadb-client SUNWjavadb-core SUNWjavadb-demo SUNWjavadb-docs SUNWjavadb-javadoc SUNWjavadb-service



③ 리눅스의 경우
   1) 다운로드 하기
      javadb-<version>-linux-rpm.bin
   2) 권한 확인하기
        
chmod +x javadb-<version>-linux-rpm.bin

       3) 압축풀기
          
/javadb-<version>-linux-rpm.bin

    이 명령을 실행하고 나면 javadb-<version> 디렉토리 밑에 여러 개의 RPM 패키지
Sun-javadb-*.i386.rpm이 생긴다.

       4) 수퍼 권한자로 변경하기
       5) 기존 JavaDB 삭제하기
          만약 기존에 JavaDB 설치가 되어 있으면(디폴트 설치 경로는 /opt/sun/javadb 이다)
          이를 새 버전을 설치하기 전에 삭제해야 한다.
          현재 돌아가고 있는 JavaDB 패키지의 리스트를 보는 방법은 다음과 같다.
         
rpm qa | grep sun-javadb-

          기존 패키지를 제거하기       
         
rpm -ev sun-javadb-common sun-javadb-client sun-javadb-core sun-javadb-demo sun-javadb-docs sun-javadb-javadoc


        6) 새 JavaDB 패키지 설치하기

cd javadb-<version>
rpm
-ivh sun-javadb-*.rpm

       
위와 같이 JavaDB를 설치하면 demo, frameworks, javadoc, docs 그리고 lib라는 서브 디렉토리가
생긴다.
이들 서브 디렉토리가 어떤 정보를 가지고 있는지 살펴보자.

1) demo : 2개의 데모 프로그램을 가지고 있으며 database 폴더는 임베디드 애플리케이션을 어떻게 만드는 지에 대한 데모이며 programs 폴더는 클라이언트-서버 환경에서 JavaDB를 사용하는 데모이다. 이 데모는 밑에서 실행해 보도록 하겠다.
2) frameworks : 환경 변수, 데이터베이스 생성 및 작업의 셋팅을 위한 유틸리티를 가지고 있다.
3) javadoc : 예상 했겠지만 API 관련 문서가 있으며 jdbc3와 jdbc4 폴더로 나뉘어져 있다.
4) docs : JavaDB의 셋업 및 어드민, 레퍼런스 가이드가 있다.
5) lib : JAR 파일과 같은 패키지 된 JavaDB 라이브러리가 있다.

4. JavaDB 실행하기

설치를 마쳤으면 이제 JavaDB를 가동시켜 보자. 가동하기 전 현재 환경 셋업이 잘 되었는지 테스트 해야 한다. 테스트 하는 명령어는 다음과 같다.

java org.apache.derby.tools.sysinfo -cp embedded SimpleApp.class


명령어를 실행하면 다음과 같은 결과 화면이 나온다.
 

이 테스트는 먼저 클래스 경로를 찾고 라이브러리와 클래스를 찾는다.
이 테스트가 성공적으로 끝나면 화면과 같은 메시지가 나온다.

그럼 이제 Derby 프로그램을 실행시켜 보자.
우선 실행할 프로그램은 SimpleApp라는 자바 프로그램이다. 이 프로그램은 설치 시 예제로 들어가 있으며 기본적인 커넥션 얻는 법부터 SQL 문을 수행하는 예제이다. 소스는 다음과 같다.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class SimpleApp
{
   
/* the default framework is embedded*/
   
public String framework = "embedded";
   
public String driver = "org.apache.derby.jdbc.EmbeddedDriver";
   
public String protocol = "jdbc:derby:";

   
public static void main(String[] args)
   
{
       
new SimpleApp().go(args);
   
}

   
void go(String[] args)
   
{
       
/* parse the arguments to determine which framework is desired*/
        parseArguments
(args);

       
System.out.println("SimpleApp starting in " + framework + " mode.");

       
try
       
{
           
/*
               The driver is installed by loading its class.
               In an embedded environment, this will start up Derby, since it is not already running.
             */

           
Class.forName(driver).newInstance();
           
System.out.println("Loaded the appropriate driver.");

           
Connection conn = null;
           
Properties props = new Properties();
            props
.put("user", "user1");
            props
.put("password", "user1");

           
/*
               The connection specifies create=true to cause
               the database to be created. To remove the database,
               remove the directory derbyDB and its contents.
               The directory derbyDB will be created under
               the directory that the system property
               derby.system.home points to, or the current
               directory if derby.system.home is not set.
             */

            conn
= DriverManager.getConnection(protocol +
                   
"derbyDB;create=true", props);

           
System.out.println("Connected to and created database derbyDB");

            conn
.setAutoCommit(false);

           
/*
               Creating a statement lets us issue commands against
               the connection.
             */

           
Statement s = conn.createStatement();

           
/*
               We create a table, add a few rows, and update one.
             */

            s
.execute("create table derbyDB(num int, addr varchar(40))");
           
System.out.println("Created table derbyDB");
            s
.execute("insert into derbyDB values (1956,'Webster St.')");
           
System.out.println("Inserted 1956 Webster");
            s
.execute("insert into derbyDB values (1910,'Union St.')");
           
System.out.println("Inserted 1910 Union");
            s
.execute(
               
"update derbyDB set num=180, addr='Grand Ave.' where num=1956");
           
System.out.println("Updated 1956 Webster to 180 Grand");

            s
.execute(
               
"update derbyDB set num=300, addr='Lakeshore Ave.' where num=180");
           
System.out.println("Updated 180 Grand to 300 Lakeshore");

           
/*
               We select the rows and verify the results.
             */

           
ResultSet rs = s.executeQuery(
                   
"SELECT num, addr FROM derbyDB ORDER BY num");

           
if (!rs.next())
           
{
               
throw new Exception("Wrong number of rows");
           
}

           
if (rs.getInt(1) != 300)
           
{
               
throw new Exception("Wrong row returned");
           
}

           
if (!rs.next())
           
{
               
throw new Exception("Wrong number of rows");
           
}

           
if (rs.getInt(1) != 1910)
           
{
               
throw new Exception("Wrong row returned");
           
}

           
if (rs.next())
           
{
               
throw new Exception("Wrong number of rows");
           
}

           
System.out.println("Verified the rows");

            s
.execute("drop table derbyDB");
           
System.out.println("Dropped table derbyDB");

           
/*
               We release the result and statement resources.
             */

            rs
.close();
            s
.close();
           
System.out.println("Closed result set and statement");

           
/*
               We end the transaction and the connection.
             */

            conn
.commit();
            conn
.close();
           
System.out.println("Committed transaction and closed connection");

           
/*
               In embedded mode, an application should shut down Derby.
               If the application fails to shut down Derby explicitly,
               the Derby does not perform a checkpoint when the JVM shuts down, which means
               that the next connection will be slower.
               Explicitly shutting down Derby with the URL is preferred.
               This style of shutdown will always throw an "exception".
             */

           
boolean gotSQLExc = false;

           
if (framework.equals("embedded"))
           
{
               
try
               
{
                   
DriverManager.getConnection("jdbc:derby:;shutdown=true");
               
}
               
catch (SQLException se)
               
{
                    gotSQLExc
= true;
               
}

               
if (!gotSQLExc)
               
{
                   
System.out.println("Database did not shut down normally");
               
}
               
else
               
{
                   
System.out.println("Database shut down normally");
               
}
           
}
       
}
       
catch (Throwable e)
       
{
           
System.out.println("exception thrown:");

           
if (e instanceof SQLException)
           
{
                printSQLError
((SQLException) e);
           
}
           
else
           
{
                e
.printStackTrace();
           
}
       
}

       
System.out.println("SimpleApp finished");
   
}

   
static void printSQLError(SQLException e)
   
{
       
while (e != null)
       
{
           
System.out.println(e.toString());
            e
= e.getNextException();
       
}
   
}

   
private void parseArguments(String[] args)
   
{
       
int length = args.length;

       
for (int index = 0; index < length; index++)
       
{
           
if (args[index].equalsIgnoreCase("jccjdbcclient"))
           
{
                framework
= "jccjdbc";
                driver
= "com.ibm.db2.jcc.DB2Driver";
                protocol
= "jdbc:derby:net://localhost:1527/";
           
}
           
if (args[index].equalsIgnoreCase("derbyclient"))
           
{
                framework
= "derbyclient";
                driver
= "org.apache.derby.jdbc.ClientDriver";
                protocol
= "jdbc:derby://localhost:1527/";
           
}
       
}
   
}
}

 
이 소스를 실행하면 다른 DB에 접속하는 법과 다른 점은 없다.
 

지금까지 JavaDB의 기본적인 설명을 다루었다. JavaDB를 사용해보면서 느낀 점은 가볍다는
것이었다. 향후 임베디드 시장에서의 활약을 기대해 보지만 이를 뚫기 위해 넘어야 할 난관이
많으며 이 중 오라클에서 Oracle Berkeley DB라는 오픈소스 기반 Lightweight 
데이터베이스와의 경쟁이 그 하나이다. 오라클은 Derby와 Oracle Berkeley DB의 성능을 비교한
문서를 공개하며 성능 이슈를 재기하고 있다. 임베디드 시장에서의 두 데이터베이스간의 활약이
기대하며 기고를 마친다.

참조 문헌 :
JavaDB 설치: http://developers.sun.com/javadb/downlo ··· ons.html
아파치 Derby 소개: http://db.apache.org/derby/docs/dev/getstart/
오라클 버클리 DB 소개: http://www.oracle.com/technology/produc ··· dex.html

"Java SE" 카테고리의 다른 글

Posted by 1010