2011년 5월 22일 일요일

CMP 엔티티 빈에서 Oracle BLOB 타입 사용하기


나는 고객으로부터 BLOB 데이터 타입을 그들의 CMP 엔티티 빈에서 사용하기 원하다는 메일을 받았다. 그들은 오라클 데이터베이스의 BLOB 데이터 타입으로 저장된 이미지를 자신들의 CMP 엔티티 빈의 BLOB 데이터 타입 필드와 메핑 시키길 원했다. J2EE 어플리케이션에서 CLOB와 BLOB 타입의 조작은 상당히 도전적인 일이다. 이 글에서 나는 어떻게 CMP 엔티티 빈에서 BLOB 데이터 타입 사용을 할 수 있는지 그 예를 제시하고 토론할 것이다.
오라클과 같은 관계형 데이터베이스 안에서 큰 객체를 저장하기 위해서 CLOB, BLOB 타입의 사용한다. BLOB는 이미지, 영상등 Binary형의 큰 객체를, CLOB는 character 기반의 큰 객체를 저장 하는데 사용한다.
JDBC에는 CLOB, BLOB 데이터 타입을 조작하기 위해서 이에 대응하는 java.sql.Clob, java.sql.Blob 자바 타입이 정의 되어있다. 하지만 이들 타입은 직렬화되지 않았기 때문에 엔티티빈에서 사용할수 없고, java.sql.Clob, java.sql.Blob 타입을 CMP 엔티티빈의 필드에 정의할수 없다.
만일 데이터베이스 안에 BLOB 컬럼을 사용하고 싶으면 CMP 필드에는 byte[]을 선언하여 BLOB 타입과 메핑 시켜야 하며, CLOB 컬럼을 사용한다면 java.lang.String 이나 char[]을 CMP 필드에 선언하여 사용하여야 한다.

엔티티빈의 예제
우리가 회사안에서 보안을 목적으로 직원들의 사진을 데이트베이스안에 저장하고 싶을수도 있을것이다. 우리는 직원들의 사진을 다루기 위해서 EmployeePicture 엔티티 빈을 사용할 것이고 컨테이너 관리 필드는 empno, picture 두 이며, picture 필드는 BLOB타입이라 byte[]로 정의핸다.
public abstract class EmployeePictureBean implements EntityBean {
....
public abstract byte[] getPicture();
public abstract void setPicture(byte[] newPicture);
public Long ejbCreate(Long empno, byte[] newPicture) {
setEmpno(empno);
setPicture(newPicture);
return empno;
}
 public void ejbPostCreate(Long empno, byte[] newPicture) {
}
...
}


이 예제는 OC4J 컨테이너를 이용하여 디플로이 되었다. OC4J에서 사용하는 디플로이 디스크립터 orion-ejb-jar.xml 파일에 CMP의 O-R 메핑을 다음과 같이 시켜준다. 만일 다른 WAS 장비를 사용한다면 그에 맞게 고쳐서 메핑 시켜준다.
<entity-deployment name="EmployeePicture" data-source="jdbc/OracleDS"
table="EMPPIC">
<primkey-mapping>
<cmp-field-mapping name="empno" persistence-name="EMPNO"
persistence-type="NUMBER(8)"/>
</primkey-mapping>
<cmp-field-mapping name="empno" persistence-name="EMPNO"
persistence-type="NUMBER(8)"/>
<cmp-field-mapping name="picture" persistence-name="PICTURE"
persistence-type="BLOB"/>
</entity-deployment>


클라이언트 프로그램
BLOB 컬럼을 다루기 위해서 CMP 엔티티 빈을 위한 클라이언트에는 특별한 것이 없다. 다른 거라고는 이미지 파일 데이터 베이스에 업데이트 하는데 BufferedInputStream을 사용하고, 데이터 읽을 때는 OutputStream을 사용한다는 것이다. 여기서 업데이트는 CMP에 이미지를 전송하는 경우이고, 읽는 경우는 CMP로부터 이미지를 받아오는 경우이다.
File imgFile = new File(fileName);
long imgFileSize= imgFile.length();
byte byteValue[] = new byte[(int)imgFileSize];
InputStream is = new BufferedInputStream(new FileInputStream(imgFile));
int len = is.read(byteValue);
if(len!=imgFileSize) {
 System.out.println(“Read bytes did not equal file size on directory”);
} else {
 EmployeePictureLocal employeePicture = empHome.create(empNo , byteValue);
}


결과
우리는 java.sql.Blob 타입의 필드를 CMP 엔티티 빈에서 직접적으로 사용할 수 없었지만 CMP 엔티티 빈 필드에 byte[] 타입을 설정함으로써 BLOB 타입을 조작할 수 있게 되었다. 한 가지 유의해야 할 것은 25메가 이상되는 자료를 데이터베이스에 저장하는 것은 심각하게 고려해봐야 한다.

댓글 없음:

댓글 쓰기

ETL 솔루션 환경

ETL 솔루션 환경 하둡은 대용량 데이터를 값싸고 빠르게 분석할 수 있는 길을 만들어줬다. 통계분석 엔진인 “R”역시 하둡 못지 않게 관심을 받고 있다. 빅데이터 역시 데이터라는 점을 볼때 분산처리와 분석 그 이전에 데이터 품질 등 데이...