前几天一直在研究Oracle Text,其中用到了Blob类型,如果用过Oracle数据库并且用Blob类型存储文件(word, excel,txt…)的同学来说,肯定不陌生了。现在就做个笔记。
Blob类型字段是Oracle数据库中的一个修饰属性,他可以实现对文本,视频,图片等的存储。视频好像可以存储4G一下的内容,可以参考:http://www.cnblogs.com/wuhenke/archive/2010/10/25/1860809.html(感谢作者的提供)。
接下来让我一起学习一下:
首先 创建一个数据库带有Blob字段的表:blob_test
create table blob_test(
id number,
name varchar2(50),
word blob
)
,数据库的表已经建立完成,接下来连接数据库,
package demo;
import java.sql.Connection;
import java.sql.DriverManager;
/*
*@Author koala
*@version CreateTime 2016年10月23日下午7:42:25
*@Function oracle DBConnect
*/
public class DBConnection {
public static Connection getDBConnection() throws Exception {
Connection con = null;
String driver = "oracle.jdbc.driver.OracleDriver";// database driver
String url = "jdbc:oracle:thin:@localhost:1521:ORCL";// database URL
String user = "C##koala"; // database name
String password = "123456"; // database Password
Class.forName(driver);
con = DriverManager.getConnection(url, user, password);
return con;
}
}
数据库的连接部分也写完来,接下来让我写一个上传和一个下载的类,
package demo;
import java.io.*;
import java.sql.*;
import oracle.jdbc.OraclePreparedStatement;
import oracle.jdbc.OracleResultSet;
import oracle.sql.BLOB;
import demo.DBConnection;
/*
*@Author koala
*@version CreateTime 2016年10月23日下午7:58:17
*@Function blob_test 用blob字段进行上传
*/
public class Blob_test {
public static void main(String[] args) throws SQLException {
Connection con = null;
long start = System.currentTimeMillis(); // 我们做一个上传时间的测试
OraclePreparedStatement pstmt = null; //最好用OraclePreparedStatement 对象
InputStream fin = null;
OutputStream outStream = null; //输入流
String path = "e:/111.docx"; //这里的文档是我要上传的文档
File file = new File(path);
try {
con = DBConnection.getDBConnection();
con.setAutoCommit(false); //这里一定要设置false不然会报错
String sql = "insert into blob_test values(?,?,?)";
// blob字段有些特殊,因为它不是普通的存储,而是分离存储的,ORACLE使得它类似于一个对象,有引用和实体,先要创建一个空内容的对象(BLOB.empty_lob()),然后再填充或修改内容,然后再回写回去。
pstmt = (OraclePreparedStatement) con.prepareStatement(sql);
for (int i = 0; i < 3; i++)
{
String name = "koala_" + i;
int id = 1;
pstmt.setInt(1, id + i);
pstmt.setString(2, name);
Blob word = BLOB.empty_lob();
pstmt.setBlob(3, word);
pstmt.execute();
}
System.out.println("insert is finally");
Statement stmt = con.createStatement();
// SELECT <BLOB字段> FROM <表名称> WHERE <关键字>=<插入关键值> FOR UPDATE;--FOR UPDATE是必须的。
//其实也就是得到具体的行和列,然后去更新blob的内容。
OracleResultSet rs = (OracleResultSet) stmt.executeQuery("select id,word from blob_test for update");
while (rs.next()) {
//得到word(blob)字段,给字段写入内容。
BLOB blob = (BLOB) rs.getBlob("word");
outStream = blob.getBinaryOutputStream();
fin = new FileInputStream(file);
byte[] b = new byte[blob.getBufferSize()];
int len = 0;
while ((len = fin.read(b)) != -1) {
outStream.write(b, 0, len);
}
fin.close();
outStream.flush();
outStream.close();
}
System.out.println("update is finally");
//提交操作
con.commit();
}
catch (Exception e) {
e.printStackTrace();
}
con.close();
long end = System.currentTimeMillis();
//计算上传一共花来多长的时间
System.out.println(end - start);
}
}
这样文件的上传操作就写完了,接下来我们看一下如何做文件的下载
其实下载过程也是很简单的,和上传操作类似,也是需要找到该条记录,然后找到blob字段,最后将blob字段的内容输出到文件里面。
package demo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import oracle.jdbc.OracleResultSet;
import oracle.sql.BLOB;
/*
*@Author koala
*@version CreateTime 2016年10月23日下午8:37:05
*@Function 获取数据库中blob的数据
*/
public class getBlob_test {
public static void main(String[] args) throws SQLException {
Connection con = null;
long start = System.currentTimeMillis();
String path = "E:\\222.docx"; //目标文件
File file = new File(path);
try {
con = DBConnection.getDBConnection();
con.setAutoCommit(false);
Statement stmt = con.createStatement();
OracleResultSet rs = (OracleResultSet) stmt.executeQuery("select id,word from blob_test where id=1");
if (rs.next()) {
BLOB blob = (BLOB) rs.getBlob("word");
FileOutputStream output = new FileOutputStream(file);
InputStream input = blob.getBinaryStream();
byte[] buffer = new byte[blob.getBufferSize()];
// 如果用1024可能会丢失一些内容,所以我们直接写blob内容最大的范围
int len = 0;
while ((len = input.read(buffer)) != -1) {
output.write(buffer, 0, len);
}
input.close();
output.flush();
output.close();
System.out.println("download is finally");
}
}
catch (Exception e) {
e.printStackTrace();
}
con.close();
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
这样文档的上传和下载功能就完成了,我这里只是以word为例,有兴趣的同学可以换成jpg,excel,pdf均可以。
最后总结一下,blob字段作为oracle数据库中存放大文件的典型代表,很方便我们对文档内容进行存储,从而可以不用将文件存放到服务器下,大大的减少来磁盘的消耗,最大可支持4G内容的操作,但是一般也不会用到这么大文件.基于blob字段之后,将会用到Oracle Text技术对文档内容进行检索。下篇继续介绍。。。