1 Oracle数据库有以下几种大对象:
历史上,大对象数据的处理向来是rdbms的'锦上添花',对于这种类型数据的处理,一般数据库厂商{历史上,过去时}使用的方法是:在相关列上保存指向操作系统文件的指针,数据存储于这些文件.但是,由此带来了一系列的问题:
*维护的代价{管理,例如备份/恢复的不便};
*事务的控制/性能的考虑{这些字段一般不能回滚、无优化};
*标准性{没有统一标准,代码和列类型\列数据都是依赖具体数据库的};
Oracle不同版本的lob类型比较:
7& later:{内部的、只能有一列、顺序存取、查询返回数据}
-long 长文本 2G
-raw 固定长度的二进制数据 2000 Bytes
-long raw 可变长度的二进制数据 2G
Just8i & later:{内外部的、能有N列、顺序随机存取、查询返回指针}
-blob 内部二进制数据 4G {以字节为处理单位}
-clob 内部文本数据 4G {以字符为处理单位}
-nclob 内部根据字符集而定的字符数据 4G {以字符为处理单位}
-BFile 外部外部二进制文件 {以字节为处理单位}
{内部指和表一样存放在Oracle数据库的某个段中,而外部是指存放于独立于Oracle的操作系统文件}
2 对大对象来说:
*insert意味着插入定位器和null值(同时建立对lob列的Index);
*update意味着更新lob的全部{不能更新某个区域}
*delete意味着删除定位器和内容;
3 实例:
3.1 使用BLOB:
*创建表
CREATE TABLE "BIGFOU"."T_VIDEO"("ID" NUMBER NOT NULL, "VIDEO"
BLOB NOT NULL,
CONSTRAINT "PK_BIGFOU_VIDEO" UNIQUE("ID") USING INDEX TABLESPACE "BIGFOU")
//主键,其中约束存储于bigfou表空间中
TABLESPACE "BIGFOU" //表空间
LOB("VIDEO") STORE AS ( TABLESPACE "BIGFOU" //对于VIDEO这个lob列来说,存储于bigfou表空间,
ENABLE STORAGE IN ROW //按行存储
NOCACHE) //不启用高速缓存
*写blob字段
写blob字段的一般方法是利用java或者其他语言编程写入(当然也可以使用plsql);
-java实现:
java.sql包里面包含了对标准blob和clob sql类型的映射接口,public interface Blob和public interface Clob
通过ResultSet的GetBlob方法可以获得blob接口,这两个接口供不同的厂商继承来实现对专有数据库的支持,Oracle提供了BLOB类实现Blob接口,并提供了操作blob列的方法。
public static void main(String[] args) {
// TODO Auto-generated method stub
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
OutputStream os = null;
FileInputStream fis = null;
int bs = 0;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:oraDB","bigfou","---");
conn.setAutoCommit(false);
stat = conn.createStatement();
stat.executeUpdate("insert into t_video(id,video) values(1,empty_blob())");
rs = stat.executeQuery("select video from t_video where id = 1");
rs.next();
oracle.sql.BLOB blo = (oracle.sql.BLOB)rs.getBlob(1);
os = blo.getBinaryOutputStream();
bs = blo.getBufferSize();
fis = new FileInputStream("D://Temp//MPlayer-CVS-20040808-K&K//mplayer.exe");
byte[] buf = new byte[bs];
int length = 0;
while(true)
{
length = fis.read(buf);
if(length == -1) break;
os.write(buf,0,length);
}
os.close();
os = null;
fis.close();
fis = null;
conn.commit();
conn.setAutoCommit(true);
conn.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
-plsql实现:
*读blob字段
-用plsql developer:直接使用类似于select video from bigfou.t_video where id=1的语句查询,然后在结果视图里面导出blob为操作系统文件即可;
-用java
...
InputStream is = null;
FileOutputStream fos = null;
byte[] buf = null;
int bs = 0;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:oraDB","bigfou","-");
conn.setAutoCommit(false);
stat = conn.createStatement();
rs = stat.executeQuery("select video from t_video where id = 1");
rs.next();
oracle.sql.BLOB blo = (oracle.sql.BLOB)rs.getBlob(1);
bs = blo.getBufferSize();
buf = new byte[bs];
int length = 0;
is = blo.getBinaryStream();
fos = new FileOutputStream("d://test.exe");
while(true) {
length = is.read(buf);
if(length == -1) break;
fos.write(buf,0,length);
}
fos.close();
fos = null;
is.close();
is = null;
conn.commit();
conn.setAutoCommit(true);
conn.close();
...