java读写Oracle Blob字段

Java中级篇 同时被 2 个专栏收录
19 篇文章 0 订阅
10 篇文章 0 订阅

前几天一直在研究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技术对文档内容进行检索。下篇继续介绍。。。

  • 2
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值