处理大数据类型
二进制类型
Vastbase G100提供两种不同的方法存储二进制数据。二进制数据可以使用二进制数据类型BYTEA存储在表中,或者使用大对象特性以一种特殊的格式将二进制数据存储在一个独立的表中,然后通过在表中保存一个类型为 OID 的值来引用该表。
BYTEA
使用BYTEA类型存储二进制数据,可以用getBytes(),setBytes()进行读写。
例如:
CREATE TABLE images (imgname text, img bytea);
插入记录
File file = new File("myimage.gif");
FileInputStream fis = new FileInputStream(file);
byte[] b = new byte[(int)file.length()];
fis.read(b);
PreparedStatement ps = conn.prepareStatement("INSERT INTO images VALUES (?, ?)");
ps.setString(1, file.getName());
ps.setBytes(2, b);
ps.executeUpdate();
ps.close();
fis.close();
在这里,数据存储在byte[]中,使用setBytes()方法来实现数据写入。
读取记录
PreparedStatement ps = conn.prepareStatement("SELECT img FROM images WHERE imgname = ?");
ps.setString(1, "myimage.gif");
ResultSet rs = ps.executeQuery();
while (rs.next())
{
byte[] imgBytes = rs.getBytes(1);
// use the data in some way here
}
rs.close();
ps.close();
在这里,二进制数据被读取为byte[] 。
BLOB
使用BLOB 类型存储二进制数据,可以用getBlob(),setBlob(),getBinaryStream(),setBinaryStream()进行读写。
例如:
CREATE TABLE test_blob(uid integer, blob_text blob);
插入记录
File file = new File("myimage.gif");
FileInputStream fis = new FileInputStream(file);
PreparedStatement ps = conn.prepareStatement("INSERT INTO test_blob VALUES (?,?)");
ps.setInt(1, 1);
ps.setBinaryStream(2, fis, (int)file.length());
ps.executeUpdate();
ps.close();
fis.close();
在这里,setBinaryStream()将一组字节从流传输到Blob类型的列中。setBinaryStream的长度参数必须正确。
也可以使用setBlob()方法来实现数据写入。
File file = new File("myimage.gif");
FileInputStream fis = new FileInputStream(file);
Blob blob = new PGBlob();
byte[] tmp = new byte[(int)file.length()];
fis.read(tmp);
blob.setBytes(1L, tmp);
PreparedStatement ps = conn.prepareStatement("INSERT INTO test_blob VALUES (?,?)");
ps.setInt(1, 2);
ps.setBlob(2, blob);
ps.executeUpdate();
ps.close();
fis.close();
读取记录
PreparedStatement ps = conn.prepareStatement("SELECT blob_text FROM test_blob WHERE uid= ?");
ps.setInt(1, 1);
ResultSet rs = ps.executeQuery();
while (rs.next())
{
Blob blob = rs.getBlob("blob_text");
InputStream in = blob.getBinaryStream();
byte[] buff = new byte[1024];
in.read(buff);
// use the data in some way here
In.close();
}
rs.close();
ps.close();
在这里,二进制数据被读取为byte[],也可以使用getBinaryStream()来实现。
CLOB
使用CLOB类型存储二进制数据,可以用getCharacterStream(),setCharatcerStream()进行读写。
例如:
CREATE TABLE test_clob(uid integer, clob_text clob);
插入记录
String data = "123abc一二三";
PreparedStatement ps = conn.prepareStatement("INSERT INTO test_clob VALUES (?, ?)");
ps.setInt(1,1);
StringReader reader = new StringReader(data);
ps.setCharacterStream(2,reader,data.length())
ps.executeUpdate();
reader.close();
ps.close();
在这里,setCharacterStream()获取到字符流写入器。writer将数据写入到字符流中进行输出。
读取记录
PreparedStatement ps = conn.prepareStatement("SELECT clob_text FROM test_clob WHERE uid= ?");
ps.setString(1, 1);
ResultSet rs = ps.executeQuery();
while (rs.next())
{
Clob clob = rs.getClob("clob_text");
Reader rd = clob.getCharacterStream();
char[] str = new char[1024];
while (true) {
int i = rd.read(str);
if (-1 == i) {
break;
}
// use the data in some way here
}
}
rs.close();
ps.close();
在这里,二进制数据被读取为char[]。
大对象功能
使用大对象功能存储二进制数据,可以用LargeObject API进行读写。
例如:
CREATE TABLE imageslo (imgname text, imgoid oid);
插入记录
// All LargeObject API calls must be within a transaction block
conn.setAutoCommit(false);
// Get the Large Object Manager to perform operations with
LargeObjectManager lobj = conn.unwrap(org.postgresql.PGConnection.class).getLargeObjectAPI();
// Create a new large object
long oid = lobj.createLO(LargeObjectManager.READ | LargeObjectManager.WRITE);
// Open the large object for writing
LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);
// Now open the file
File file = new File("myimage.gif");
FileInputStream fis = new FileInputStream(file);
// Copy the data from the file to the large object
byte buf[] = new byte[2048];
int s, tl = 0;
while ((s = fis.read(buf, 0, 2048)) > 0)
{
obj.write(buf, 0, s);
tl += s;
}
// Close the large object
obj.close();
// Now insert the row into imageslo
PreparedStatement ps = conn.prepareStatement("INSERT INTO imageslo VALUES (?, ?)");
ps.setString(1, file.getName());
ps.setLong(2, oid);
ps.executeUpdate();
ps.close();
fis.close();
// Finally, commit the transaction.
conn.commit();
读取记录
// All LargeObject API calls must be within a transaction block
conn.setAutoCommit(false);
// Get the Large Object Manager to perform operations with
LargeObjectManager lobj = conn.unwrap(org.postgresql.PGConnection.class).getLargeObjectAPI();
PreparedStatement ps = conn.prepareStatement("SELECT imgoid FROM imageslo WHERE imgname = ?");
ps.setString(1, "myimage.gif");
ResultSet rs = ps.executeQuery();
while (rs.next())
{
// Open the large object for reading
long oid = rs.getLong(1);
LargeObject obj = lobj.open(oid, LargeObjectManager.READ);
// Read the data
byte buf[] = new byte[obj.size()];
obj.read(buf, 0, obj.size());
// Do something with the data read here
// Close the object
obj.close();
}
rs.close();
ps.close();
// Finally, commit the transaction.
conn.commit();
字符类型
Vastbase G100中TEXT类型与VARCHAR类型都是可变长的字符类型,区别在于VARCHAR类型通过VARCHAR(n)中的n来限制最大长度,而TEXT类型没有。TEXT类型与VARCHAR类型几乎没有性能差别,TEXT类型最多可存储1G数据。
使用TEXT类型存储数据时,可用getString(),getCharacterStream(),setString(), setCharacterStream()来进行读写。
例如:
CREATE TABLE images (id int, msg text);
插入记录
File file = new File("myimage.gif");
Reader reader = new InputStreamReader(new FileInputStream(file));
PreparedStatement ps = conn.prepareStatement("INSERT INTO images VALUES (?, ?)");
ps.setString(1, 12);
ps.setCharacterStream (2, reader);
ps.executeUpdate();
ps.close();
fis.close();
如果数据内容已经在String中,那么也可以使用setString()方法来实现数据写入。
读取记录
PreparedStatement ps = conn.prepareStatement("SELECT msg FROM images WHERE id= ?");
ps.setString(1, 12);
ResultSet rs = ps.executeQuery();
while (rs.next())
{
String imgBytes = rs.getString(1);
// use the data in some way here
}
rs.close();
ps.close();
在这里,TEXT数据被读取为String,也可以调用getCharacterStream()处理 。