포스트그레SQL2개 제공 바이너리 토토 캔를 저장하는 독특한 방법. 바이너리 토토 캔를 저장할 수 있습니다. 토토 캔 유형을 사용하는 테이블바이테아또는 작성자 바이너리 데이터를 저장하는 Large Object 기능을 사용하여 특별한 형식으로 별도의 테이블을 만들고 해당 테이블을 다음과 같이 참조합니다. 유형 값 저장oid당신의 테이블.
어떤 방법이 적절한지 결정하려면 다음을 수행해야 합니다. 각 방법의 한계를 이해합니다.바이테아토토 캔 유형은 저장에 적합하지 않습니다. 대량의 바이너리 토토 캔. 유형의 열인 동안바이테아최대 1GB의 바이너리 데이터를 저장할 수 있습니다. 이렇게 큰 값을 처리하려면 엄청난 양의 메모리가 필요합니다. 바이너리 데이터를 저장하는 데는 Large Object 방법이 더 적합합니다. 매우 큰 값을 저장하는 데에는 한계가 있습니다. 특히 대형 개체가 포함된 행 삭제 참조는 대형 개체를 삭제하지 않습니다. 대형 삭제 개체는 수행해야 하는 별도의 작업입니다. 대형 모든 사람이 연결되어 있기 때문에 객체에도 보안 문제가 있습니다. 데이터베이스는 다음과 같은 경우에도 대형 개체를 보거나 수정할 수 있습니다. 해당 행을 포함하는 행을 보거나 업데이트할 수 있는 권한이 없습니다. 대형 객체 참조.
버전 7.2는 다음의 첫 번째 릴리스였습니다.JDBC다음을 지원하는 드라이버바이테아데이터 유형. 이것의 소개
7.2의 기능은 다음과 같이 동작을 변경했습니다.
이전 릴리스와 비교. 7.2부터 메소드getBytes(), setBytes(), getBinaryStream()그리고setBinaryStream()작동바이테아토토 캔 유형. 7.1 이하에서는 이러한 방법이
에서 운영됨oid연관된 데이터 유형
대형 객체로. 드라이버를 다시 원래 상태로 되돌릴 수 있습니다.
속성을 설정하여 이전 7.1 동작호환 가능에연결값에 대한 반대7.1.
다음을 사용하려면바이테아당신이 해야 할 데이터 유형
간단히 다음을 사용하세요.getBytes(),
setBytes(), getBinaryStream()또는setBinaryStream()방법.
대형 개체 기능을 사용하려면 다음 중 하나를 사용할 수 있습니다.대형객체클래스에서 제공하는 클래스포스트그레SQL JDBC드라이버 또는 다음을 사용하여getBLOB()그리고setBLOB()방법.
중요:당신은 내부의 대형 개체에 접근해야 합니다.SQL트랜잭션 차단. 당신 호출하여 거래 블록을 시작할 수 있습니다.
setAutoCommit(false).
참고:향후 릴리스에서는JDBC운전사, 그
getBLOB()그리고setBLOB()메소드가 더 이상 상호 작용하지 않을 수 있습니다. Large Objects를 사용하고 대신 데이터 유형에서 작동합니다.바이테아. 따라서 다음을 수행하는 것이 좋습니다. 사용하다대형객체API사용하려는 경우 대형 개체.
예 31-8에는 다음을 사용하여 바이너리 데이터를 처리하는 방법에 대한 몇 가지 예가 포함되어 있습니다. 포스트그레SQLJDBC운전자.
예 31-8. 바이너리 데이터 처리JDBC
예를 들어, 파일이 포함된 테이블이 있다고 가정해 보겠습니다. 이미지 이름을 지정하고 이미지를 a에 저장하려고 합니다.바이테아열:
CREATE TABLE 이미지(imgname 텍스트, img bytea);
이미지를 삽입하려면 다음을 사용하세요:
파일 파일 = 새 파일("myimage.gif");
FileInputStream fis = new FileInputStream(파일);
ReadyStatement ps = conn.prepareStatement("이미지 값에 삽입 (?, ?)");
ps.setString(1, file.getName());
ps.setBinaryStream(2, fis, file.length());
ps.executeUpdate();
ps.close();
fis.close();
여기,setBinaryStream()설정된 바이트 수를 스트림에서 열로 전송합니다.
유형바이테아. 이것도 그럴 수도 있었지
다음을 사용하여 완료했습니다.setBytes()방법
이미지의 내용이 이미 a에 있는 경우바이트[].
이미지 검색이 더욱 쉬워졌습니다. (우리는 사용합니다PreparedStatement여기 있지만성명클래스도 동일하게 사용할 수 있습니다.)
PreparedStatement ps = con.prepareStatement("IMGNAME = ? WHERE imgname = ?");
ps.setString(1, "myimage.gif");
ResultSet rs = ps.executeQuery();
if (rs != null)
동안(rs.next())
byte[] imgBytes = rs.getBytes(1);
// 여기에서 어떤 방식으로든 데이터를 사용합니다.
rs.close();
여기서 바이너리 데이터는 다음과 같이 검색되었습니다.바이트[]. 당신은 a를 사용할 수 있었습니다입력스트림대신 개체를 사용하세요.
또는 매우 큰 파일을 저장하고
다음을 사용하고 싶습니다.대형객체
API파일을 저장하려면:
CREATE TABLE 이미지lo(imgname 텍스트, imgoid oid);
이미지를 삽입하려면 다음을 사용하세요:
// 모든 LargeObject API 호출은 트랜잭션 블록 내에 있어야 합니다.
conn.setAutoCommit(false);
// 작업을 수행하기 위해 Large Object Manager를 가져옵니다.
LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();
// 새로운 대형 객체 생성
int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
// 쓰기를 위해 대형 객체를 엽니다.
LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);
// 이제 파일을 엽니다.
파일 file = new File("myimage.gif");
FileInputStream fis = new FileInputStream(파일);
// 파일의 데이터를 대형 객체에 복사합니다.
바이트 buf[] = 새 바이트[2048];
int s, tl = 0;
while ((s = fis.read(buf, 0, 2048)) 0)
obj.write(buf, 0, s);
tl += s;
// 대형 객체를 닫습니다.
obj.close();
// 이제 이미지로에 행을 삽입합니다.
ReadyStatement ps = conn.prepareStatement("이미지에 삽입 VALUES (?, ?)");
ps.setString(1, file.getName());
ps.setInt(2, oid);
ps.executeUpdate();
ps.close();
fis.close();
대형 개체에서 이미지 검색 중:
// 모든 LargeObject API 호출은 트랜잭션 블록 내에 있어야 합니다.
conn.setAutoCommit(false);
// 작업을 수행하기 위해 Large Object Manager를 가져옵니다.
LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();
ReadyStatement ps = con.prepareStatement("이미지에서 imgoid를 선택하세요. WHERE imgname = ?");
ps.setString(1, "myimage.gif");
ResultSet rs = ps.executeQuery();
if (rs != null)
동안(rs.next())
// 읽기 위해 대형 객체를 엽니다.
int oid = rs.getInt(1);
LargeObject obj = lobj.open(oid, LargeObjectManager.READ);
// 데이터 읽기
byte buf[] = 새로운 byte[obj.size()];
obj.read(buf, 0, obj.size());
// 여기에서 읽은 데이터로 작업을 수행합니다.
// 객체를 닫습니다.
obj.close();
rs.close();