이 문서는 지원되지 않는 버전의 PostgreSQL을위한 것입니다.
당신은의 동일한 페이지를 보려고 할 수 있습니다현재버전 또는 위에 나열된 다른 지원 버전 중 하나입니다.

31.7. 이진 토토 캔 저장

PostgreSQL두 가지를 제공합니다 이진 토토 캔를 저장하는 독특한 방법. 이진 토토 캔는 저장 될 수 있습니다 토토 캔 유형을 사용한 테이블BYTEA또는 by 이진 토토 캔를 특수 형식으로 별도의 테이블과 해당 테이블을 말합니다. 유형 값 저장OID당신의 테이블.

필요한 방법을 결정하려면 필요한 방법을 결정하려면 각 방법의 한계를 이해하십시오. 그만큼BYTEA토토 캔 유형은 저장에 적합하지 않습니다 다량의 이진 토토 캔. 유형의 열BYTEA최대 1GB의 이진 토토 캔를 보유 할 수 있습니다. 그러한 큰 값을 처리하려면 엄청난 양의 메모리가 필요합니다. 이진 토토 캔 저장을위한 큰 객체 방법이 더 적합합니다. 매우 큰 값을 저장하지만 자체 제한 사항이 있습니다. 구체적으로 큰 객체가 포함 된 행을 삭제합니다 참조는 큰 객체를 삭제하지 않습니다. 큰 삭제 객체는 수행 해야하는 별도의 작업입니다. 크기가 큰 객체는 또한 연결된 사람 이후 몇 가지 보안 문제가 있습니다. 토토 캔베이스는 큰 객체를보고/또는 수정할 수 있습니다. 그들은 포함 된 행을보고/업데이트 할 권한이 없습니다. 큰 객체 참조.

버전 7.2는의 첫 번째 릴리스입니다.JDBC지원하는 드라이버BYTEA데이터 유형. 이것의 소개 7.2의 기능은 행동의 변화를 다음과 같이 도입했습니다. 이전 릴리스와 비교했습니다. 7.2 이후, 방법getBytes (), setBytes (), getBinaryStream ()setBinaryStream ()BYTEA토토 캔 유형. 7.1 이하에서 이러한 방법 에서 작동OID토토 캔 유형 관련 큰 물체로. 운전자를 다시 되돌릴 수 있습니다 재산을 설정하여 기존 7.1 행동호환onConnection값에 대한 개체7.1.

사용하려면BYTEA토토 캔 유형 간단히 사용하십시오getBytes (), setBytes (), getBinaryStream ()또는setBinaryStream ()방법.

큰 객체 기능을 사용하려면를 사용할 수 있습니다.BARGEOBJECT클래스가 제공하는 클래스postgresql JDBC드라이버 또는 사용함으로써getBlob ()andsetBlob ()방법.

중요 :당신은 an 내에서 큰 개체에 액세스해야합니다.SQL트랜잭션 블록. 너 전화를 통해 거래 블록을 시작할 수 있습니다setAutocommit (false).

참고 :향후 릴리스에서JDBC드라이버,getBlob ()andsetBlob ()메소드가 더 이상 상호 작용하지 않을 수 있습니다 큰 객체와 대신 토토 캔 유형에서 작동합니다BYTEA. 그래서 당신을 추천합니다 사용BARGEOBJECT API사용하려는 경우 큰 물건.

예 31-8postgresqlJDBC드라이버

예 31-8. 이진 데이터 처리JDBC

예를 들어 파일이 포함 된 테이블이 있다고 가정합니다. 이미지의 이름과 이미지를 a에 저장하고 싶습니다.BYTEA열 :

테이블 이미지 생성 (Imgname Text, IMG Bytea);

이미지를 삽입하려면 다음을 사용합니다.

파일 = 새 파일 ( "myimage.gif");
fileInputStream fis = 새로운 fileInputStream (file);
preparedstatement ps = conn.preparestatement ( "이미지 값 (?,?)에 삽입");
ps.SetString (1, file.getName ());
ps.setbinarystream (2, fis, file.length ());
ps.ExecuteUpdate ();
ps.close ();
fis.close ();

여기,setBinaryStream ()스트림에서 열에서 열로 세트 수를 전송합니다. 유형BYTEA. 이것은 또한 그럴 수도 있습니다 사용 완료setBytes ()메소드 이미지의 내용이 이미 A에있는 경우byte [].

이미지를 검색하는 것이 훨씬 쉽습니다. (우리는 사용준비된 상태여기, 그러나진술클래스를 동일하게 사용할 수 있습니다.)

preparedstatement ps = con.preparestatement ( "imgname =?");
ps.SetString (1, "myimage.gif");
resultSet rs = ps.ExecuteQuery ();
if (rs! = null) 
    while (rs.next ()) 
        바이트 [] imgbytes = rs.getBytes (1);
        // 여기에서 데이터를 어떤 방식으로 사용하십시오

    rs.close ();

여기서 바이너리 토토 캔가 A로 검색되었습니다byte []. 당신은를 사용할 수있었습니다입력 스트림대상 대상.

또는 매우 큰 파일을 저장하고 사용하고 싶어BARGEOBJECT API파일을 저장하려면 :

테이블 생성 imagesLo (imgname text, imgoid oid);

이미지를 삽입하려면 다음을 사용합니다.

// 모든 대형 OBJECT API 호출은 트랜잭션 블록 내에 있어야합니다.
conn.setAutocommit (false);

// 대형 객체 관리자가
BARGEOBJECTMANAGER LOBJ = ((org.postgresql.pgconnection) conn) .getLargeObjectapi ();

// 새로운 큰 객체를 만듭니다
int oid = lobj.create (bargeobjectmanager.read | margeobjectmanager.write);

// 쓰기를 위해 큰 물건을 엽니 다
BARGEOBJECT OBJ = LOBJ.OPEN (OID, BARGEOBJECTMANAGER.WRITE);

// 이제 파일을 엽니 다
파일 = 새 파일 ( "myimage.gif");
fileInputStream fis = 새로운 fileInputStream (file);

// 파일에서 큰 개체로 데이터를 복사합니다.
바이트 buf [] = 새로운 바이트 [2048];
int s, tl = 0;
while ((s = fis.read (buf, 0, 2048)) 0) 
    obj.write (buf, 0, s);
    tl += s;

// 큰 개체를 닫습니다
obj.close ();

// 이제 행을 ImagesLo에 삽입하십시오
preparedstatement ps = conn.preparestatement ( "imagesLo 값 (?,?)에 삽입");
ps.SetString (1, file.getName ());
ps.setint (2, oid);
ps.ExecuteUpdate ();
ps.close ();
fis.close ();

큰 개체에서 이미지 검색 :

// 모든 큰 대형 API 호출은 트랜잭션 블록 내에 있어야합니다.
conn.setAutocommit (false);

// 대형 객체 관리자가
BARGEOBJECTMANAGER LOBJ = ((org.postgresql.pgconnection) conn) .getLargeObjectapi ();

preparedstatement ps = con.preparestatement ( "imagelo에서 imgoid를 선택하여 imgname =?");
ps.SetString (1, "myimage.gif");
resultSet rs = ps.ExecuteQuery ();
if (rs! = null) 
    while (rs.next ()) 
        // 읽기를 위해 큰 물체를 엽니 다
        int oid = rs.getint (1);
        bargeobject obj = lobj.open (OID, BARGEOBJECTMANAGER.READ);

        // 데이터를 읽습니다
        바이트 buf [] = 새로운 바이트 [obj.size ()];
        obj.read (buf, 0, obj.size ());
        // 여기에서 읽은 데이터로 무언가를 수행하십시오

        // 객체를 닫습니다
        obj.close ();

    rs.close ();