MySQL에서 CUBRID의 변환을 생각하는 많은 개발자들이 궁금해 하는 MySQL의 BLOB타입 데이터를 CUBRID로 이전하는 방법에 대해 기술한다. 본FAQ는 http://blog.naver.com/windyhan/110052262344 블로그를 참조하여 기술하였음을 밝힌다.
이미 문서를 통하여 MySQL to CUBRID의 Data Type변경에 대해 소개하고 있다. 대부분의 경우 대응되는 Type으로의 스키마 변경으로 해결되나 Blob의 경우 약간의 작업이 필요하게 된다. 이 약간의 작업에 대해서 설명하도록 한다.
MySQL에서 사용하는 Blob타입 4종류와 각각의 허용 범위는 아래와 같다.
TinyBlob - maximum length of 255 characters.
Blob - maximum length of 65535 characters.
MediumBlob - maximum length of 16777215 characters.
LongBlob - maximum length of 4294967295 characters.
CUBRID에서 대응하는 Type인 Bit Varying의 범위는 아래와 같다.
Bit Varying(n) - n에 대한 값이 생략되면, 디폴트 길이 1,073,741,823이 가정된다. 이는 MySQL의 LongBlob을 제외한 Blob타입에 대응될 수 있다.
* MySQL의 LongBlob에 대해서는 CUBRID는 GLO라는 타입으로 대응이 가능하나 이는 다른 Tip으로 정리한다.
MySQL의 Blob을 CUBRID로 변환하는 과정을 아래의 예를 통하여 확인하고자 한다. 아래의 예시는 test_tbl이라는 테이블로 간단한 이미지를 저장한 저장해 놓은 테이블이다. 이미지의 사이즈는 30~60만 byte정도로 MySQL의 MediumBlob에 해당한다.
mysql> describe test_tbl;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| file_name | varchar(255) | YES | | NULL | |
| file_data | mediumblob | YES | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
데이터는 아래와 같이 들어있다.
데이터를 추출하기 위해 JDBC를 이용한다. file_data칼럼에 있는 이미지를 추출하는 java코드는 아래와 같다.
public void getBlobDataFromMySQL(){
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
String file_path = "pic";
try{
File curr = new File("./" + file_path);
if( !curr.exists() ){
curr.mkdir();
}
Class.forName("com.mysql.jdbc.Driver"); //드라이버 로드
conn = DriverManager.getConnection // Connection객체 가져오기
("jdbc:mysql://localhost/testdb?user=root&password=root");
String sql = "select id, file_name, file_data from test_tbl";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while(rs.next()){
int id = rs.getInt("id");
String file_name = rs.getString("file_name");
InputStream is = rs.getBinaryStream("file_data");
FileOutputStream fos = new FileOutputStream("./pic/" + file_name);
byte[] buff = new byte[2048000];
int len;
while ( (len = is.read(buff)) > 0 )
fos.write( buff, 0, len);
fos.close();
is.close();
}
rs.close();
stmt.close();
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
위의 코드를 간략히 설명하면 test_tbl 테이블의 이미지를 select 하여 pic이라는 디렉토리에 file_name 을 이름으로 하는 파일들을 생성한다. 이 파일들을 읽어서 CUBRID에 삽입할 것이다.
이제 추출한 데이터를 넣을 CUBRID테이블을 생성한다. CUBRID의 테이블 생성 예는 아래와 같다.
csql> create table test_tbl ( id integer auto_increment primary key not null, file_name varchar(255), file_data bit varying);
csql> ;x
Current transaction has been committed.
1 command(s) successfully processed.
csql> ;sc test_tbl
=== <Help: Schema of a Class> ===
<Class Name>
test_tbl
<Attributes>
id INTEGER AUTO_INCREMENT NOT NULL
file_name CHARACTER VARYING(255)
file_data BIT VARYING(1073741823)
<Constraints>
PRIMARY KEY pk_test_tbl_id ON test_tbl (id)
Current transaction has been committed.
MySQL의 BLOB 타입에서 빼낸 이미지 파일들을 CUBRID의 test_tbl의 bit varying 타입인 file_data 컬럼에 넣는다.
public void setBlobDataToCUBRID_bit(){
File curr = new File("./pic");
String[] filelist = curr.list(new BlobFileNameFilter()); ------------------------- 1
cubrid.jdbc.driver.CUBRIDConnection conn=null;
cubrid.jdbc.driver.CUBRIDPreparedStatement stmt=null;
try{
Class.forName("cubrid.jdbc.driver.CUBRIDDriver");
conn = (cubrid.jdbc.driver.CUBRIDConnection)DriverManager.getConnection
("jdbc:cubrid:127.0.0.1:33004:testdb1:dba::"); ------------------------- 2
for( int i = 0; i < filelist.length ; i++){
String filename = filelist[i];
File file = new File("./pic/" + filename);
FileInputStream in = new FileInputStream(file); ------------------------- 3
String sql = "insert into test_tbl(file_name, file_data) values ( ?,?)";
stmt=(cubrid.jdbc.driver.CUBRIDPreparedStatement)conn.prepareStatement(sql);
stmt.setString(1,filename);
stmt.setBinaryStream(2,in,(int)file.length()); ------------------------- 4
stmt.executeUpdate(); ------------------------- 5
stmt.close();
in.close();
}
conn.commit();
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
각각의 설명은 아래와 같다.
1. Bit varying 컬럼에 저장할 파일들의 리스트를 생성한다.
2. CUBRID DB의 Connection 을 가져온다.
3. 입력할 FILE의 InputStream 을 생성한다.
4. Bit Varying 타입인 file_data 컬럼에 setBinaryStream() 함수를 이용해 파라미터 바인딩을 한다.
5. insert 문을 실행한다.
위의 java파일을 컴파일 후 실행하면 test_tbl 테이블에 데이터가 삽입된다. 데이터가 제대로 들어갔는지 확인한다.
csql> select file_name, bit_length(file_data)/8 from test_tbl
csql> ;x
=== <Result of SELECT Command in Line 1> ===
file_name bit_length(file_data)/8
================================================
'DSC_0193_007.JPG' 329216
'DSC_0199_010.JPG' 266272
'DSC_0202_011.JPG' 329382
'DSC_0190_004.JPG' 419584
'DSC_0206_013.JPG' 319426
'DSC_0187_002.JPG' 321152
'DSC_0197_008.JPG' 273747
'DSC_0191_005.JPG' 391503
'DSC_0192_006.JPG' 291880
'DSC_0198_009.JPG' 169344
'DSC_0183_001.JPG' 216492
'DSC_0208_014.JPG' 345924
'DSC_0203_012.JPG' 333349
'DSC_0189_003.JPG' 262936
14 rows selected.
데이터가 잘 들어가 있는지 확인해 보았다. 질의에서 Bit_length(file_data)/8 을 한 이유는 저장된 데이터의 byte 수를 알기 위해 한 것이다. 특별히 다른 점은 없고, JDBC 표준 인터페이스를 사용하여 저장을 한 것이다.
CUBRID에 저장된 데이터를 추출하는 방법은 위의 MySQL에서 추출한 방법과 거의 같다 아래의 두가지 부분만 변경해 주면 된다.
1. 함수 이름을 변경한다.
2. MySQL Connection 연결하는 방법을 CUBRID용으로 변경한다.
[출처] MySQL의 Blob타입을 CUBRID로 변환하기 (큐브리드 공부하기) |작성자 Neo
'PHP > Mysql_이미지저장및 뷰' 카테고리의 다른 글
MySQL 쿼리에 이미지 저장 (0) | 2013.07.04 |
---|