最近研究了一下oracle中可以存储大数据量的字段,发现clob和blob很常用,可以存储的空间也很大
无奈这两个字段的操作不太方便,在网上学习了很久,总结归纳了一下,写了一些比较简单的代码。
一 操作CLOB字段
这个东西其实我感觉他是专门用来存储大数据量的字符串的,因此需要存储大量的字符串就放在这个里面,并且最最重要的就是clob字段支持字段的模糊查询!而且这个clob的操作比blob还要简单一些。
我有一张名为clobtest的表,里面有两个字段cc_id 主键,cc_sk clob类型
主键的id使用的是触发器+序列进行生成
//clob插入
public boolean WriteClob(){
try{
Connection con = getConnection(); //这个是我自己的获取数据连接的函数,下同
fileContent = getFileContent("D:/txt/a.txt","gb18030"); //这个是获取某路径上文件内容的函数,下同
System.out.println("文件长度:"+fileContent.length());
String sql = "insert into clobtest values(?,?)";
Reader clobReader = new StringReader(fileContent); //使用reader获取文本文件
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, 1);
ps.setCharacterStream(2, clobReader, fileContent.length());
//预编译将刚才的reader放进去,再把文件的长度也放进去
ps.executeUpdate();
ps.close();
con.close();
return true;
}
catch(Exception e){
e.printStackTrace();
return false;
}
}
//clob读取
public void ReadClob(){
try{
Connection con = getConnection();
String sql = "select * from clobtest where cc_sk like '%"+"
刘晓兵"+"%'"; //模糊插叙clob字段中名为 刘晓兵 的数据
PreparedStatement ps = con.prepareStatement(sql);
ResultSet r = ps.executeQuery();
while(r.next()){
System.out.println("主键:"+r.getInt(1));
//你没看错,如果里面存的全是字符串,则可以使用getString来获取
System.out.println("内容:"+r.getString(2));
}
ps.close();
con.close();
}
catch(Exception e){
e.printStackTrace();
}
}
二 操作BLOB字段
存放字符串以外的数据文件,推荐存放在blob中,他不支持模糊查询。
数据库中有一张表名为blobtest ,有两个字段bb_id 为主键, bb_sk 为blob类型
主键的id使用的是触发器+序列进行生成
public boolean WriteBlob(){
Connection con = getConnection();
try{
con.setAutoCommit(true);
Statement st = con.createStatement();
//使用Empty_BLOB()填充
String sql = "insert into blobtest values(1,Empty_BLOB()) ";
st.executeUpdate(sql);
//查询出刚才的那条初始化的数据,并行级锁定
sql = "select bb_sk from blobtest where bb_id = (select max
(bb_id) from blobtest) for update";
ResultSet r = st.executeQuery(sql);
r.next();
//将获得的java.sql.blob类型强制变为oracle.sql.BLOB
oracle.sql.BLOB blob = (oracle.sql.BLOB)r.getBlob(1);
//获取blob的输出流
OutputStream out = blob.getBinaryOutputStream();
//获取写入数据库文件的输入流
InputStream in = new FileInputStream("D:/temp/贝阿朵.jpg");
//原始大小的文件拷贝
int len = 0;
while(len!=-1){
byte[] b = new byte[4096];
len = in.read(b,0,b.length);
if(len!=-1){
b = Arrays.copyOfRange(b, 0, len);
out.write(b);
}
}
//提交缓存,必要的
out.flush();
//关闭输入输出流,必要的
out.close();
in.close();
con.close();
return true;
}
catch(Exception e){
e.printStackTrace();
return false;
}
}
blob在插入时是最复杂的,这里几方面需要注意:
1.千万不可使用预编译处理,否则会报出参数绑定错误的异常
2.回滚参数,其实是插入失败是使用的,如果你确定他会成功其实可以不要
3.输出流一定要提交缓存 out.flush() ,关闭所有你打开的各种流
4.拷贝写入文件时,按照那个方法可以将文件的初始大小拷贝进入数据库,不用担心
写入的文件为byte数组的整数倍
//blob的读取
public void readBlob(int bb_id){
try{
Connection con = getConnection();
//这个可以使用预编译
String sql = "select bb_sk from blobtest where bb_id =?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, bb_id);
ResultSet r = ps.executeQuery();
r.next();
oracle.sql.BLOB blob = (oracle.sql.BLOB)r.getBlob(1);
//获取查出来blob数据的输入流
InputStream in = blob.getBinaryStream();
OutputStream out = new FileOutputStream("D:/temp/you.jpg");
//原始长度的拷贝至某个新建的文件
int len = 0;
while(len!=-1){
byte[] b = new byte[4096];
len = in.read(b,0,b.length);
if(len!=-1){
b = Arrays.copyOfRange(b, 0, len);
out.write(b);
}
}
//提交缓存,必要的
out.flush();
//关闭输入输出流,必要的
out.close();
in.close();
con.close();
System.out.println("文件成功写在 D:/temp/you.jpg 下");
}
catch(Exception e){
e.printStackTrace();
}
}
这个没有什么可说的,比较简单可以和写入数据库进行对比
以上