BLOB(Binary Large Object)은 최대 65535자(바이트)까지 가변 길이의 데이터를 저장할 수 있는 바이너리 대형 객체입니다. 주로 이미지나 각종 파일처럼 용량이 큰 이진 데이터를 데이터베이스에 저장할 때 사용됩니다.
TEXT 필드 역시 대용량 데이터를 저장할 수 있습니다. 두 타입의 차이점은, BLOB에 저장된 데이터는 정렬·비교 시 대소문자를 구분하는 반면 TEXT 필드는 대소문자를 구분하지 않는다는 점입니다. 또한 BLOB과 TEXT 컬럼을 정의할 때는 별도의 길이를 지정하지 않습니다.
데이터베이스에 BLOB 저장하기
JDBC 프로그램으로 BLOB 타입 데이터를 데이터베이스에 저장하려면 아래 단계를 따르면 됩니다.
1단계: 데이터베이스 연결
DriverManager 클래스의 getConnection() 메서드를 사용해 데이터베이스에 연결할 수 있습니다. MySQL URL인 jdbc:mysql://localhost/sampleDB(여기서 sampleDB는 데이터베이스 이름), 사용자 이름, 비밀번호를 매개변수로 전달하면 됩니다.
String mysqlUrl = "jdbc:mysql://localhost/sampleDB"; Connection con = DriverManager.getConnection(mysqlUrl, "root", "password");
2단계: PreparedStatement 생성
Connection 인터페이스의 prepareStatement() 메서드를 사용해 PreparedStatement 객체를 생성합니다. 이때 플레이스홀더(?)가 포함된 INSERT 쿼리를 매개변수로 전달합니다.
PreparedStatement pstmt = con.prepareStatement("INSERT INTO MyTable VALUES(?, ?)");3단계: 플레이스홀더에 값 설정
PreparedStatement 인터페이스의 setter 메서드로 플레이스홀더에 값을 설정합니다. 컬럼의 데이터 타입에 맞는 메서드를 선택하세요. 예를 들어 VARCHAR 타입 컬럼에는 setString(), INT 타입 컬럼에는 setInt()를 사용합니다.
BLOB 타입이라면 setBinaryStream() 또는 setBlob() 메서드를 사용합니다. 두 메서드 모두 매개변수 인덱스를 나타내는 정수와 InputStream 객체를 인자로 받습니다.
pstmt.setString(1, "sample image");
// BLOB 타입 삽입
InputStream in = new FileInputStream("E:\\images\\cat.jpg");
pstmt.setBlob(2, in);4단계: 쿼리 실행
PreparedStatement 인터페이스의 execute() 메서드로 앞서 생성한 PreparedStatement 객체를 실행합니다.
데이터베이스에서 BLOB 읽어오기
ResultSet 인터페이스의 getBlob() 메서드는 컬럼 인덱스(정수) 또는 컬럼 이름(문자열)을 인자로 받아 해당 컬럼의 값을 Blob 객체 형태로 반환합니다.
while(rs.next()) {
rs.getString("Name");
rs.getString("Type");
Blob blob = rs.getBlob("Logo");
}Blob 인터페이스의 getBytes() 메서드는 현재 Blob 객체의 내용을 byte 배열로 반환합니다. getBlob()으로 BLOB 내용을 byte 배열에 담은 뒤, FileOutputStream 객체의 write() 메서드를 사용해 이미지 파일로 복원할 수 있습니다.
byte byteArray[] = blob.getBytes(1,(int)blob.length());
FileOutputStream outPutStream = new FileOutputStream("path");
outPutStream.write(byteArray);예제
다음 예제는 MySQL 데이터베이스에 BLOB 타입 컬럼을 포함한 테이블을 생성하고, 이미지를 삽입한 뒤 다시 읽어와 로컬 파일 시스템에 저장하는 전체 과정을 보여줍니다.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
public class BlobExample {
public static void main(String args[]) throws Exception {
// 드라이버 등록
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 연결 생성
String mysqlUrl = "jdbc:mysql://localhost/sampleDB";
Connection con = DriverManager.getConnection(mysqlUrl, "root", "password");
System.out.println("Connection established......");
// 테이블 생성
Statement stmt = con.createStatement();
stmt.execute("CREATE TABLE SampleTable( Name VARCHAR(255), Image BLOB)");
System.out.println("Table Created");
// 값 삽입
String query = "INSERT INTO SampleTable(Name,image) VALUES (?, ?)";
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setString(1, "sample image");
FileInputStream fin = new FileInputStream("E:\\images\\cat.jpg");
pstmt.setBlob(2, fin);
pstmt.execute();
// 데이터 조회
ResultSet rs = stmt.executeQuery("select * from SampleTable");
int i = 1;
System.out.println("Contents of the table are: ");
while(rs.next()) {
System.out.println(rs.getString("Name"));
Blob blob = rs.getBlob("Image");
byte byteArray[] = blob.getBytes(1,(int)blob.length());
FileOutputStream outPutStream = new
FileOutputStream("E:\\images\\blob_output"+i+".jpg");
outPutStream.write(byteArray);
System.out.println("E:\\images\\blob_output"+i+".jpg");
System.out.println();
i++;
}
}
}실행 결과
Connection established...... Table Created Contents of the table are: sample image E:\images\blob_output1.jpg