JDBC ORACLE BLOB处理

LOB,即Large Objects(大对象),是用来存储大量的二进制和文本数据的一种数据类型(一个LOB字段可存储可多达4GB的数据)。
LOB 分为两种类型:内部LOB和外部LOB。
    内部LOB将数据以字节流的形式存储在数据库的内部。因而,内部LOB的许多操作都可以参与事务,
也可以像处理普通数据一样对其进行备份和恢复操作。Oracle支持三种类型的内部LOB:
BLOB(二进制数据)  
CLOB(单字节字符数据) 
NCLOB(多字节字符数据)。
CLOB和NCLOB类型适用于存储超长的文本数据,BLOB字段适用于存储大量的二进制数据,如图像、视频、音频,文件等。


目前只支持一种外部LOB类型,即BFILE类型。在数据库内,该类型仅存储数据在操作系统中的位置信息,
而数据的实体以外部文件的形式存在于操作系统的文件系统中。因而,该类型所表示的数据是只读的,不参与事务。
该类型可帮助用户管理大量的由外部程序访问的文件.


使用JDBC来写入Blob型数据到Oracle中 :
Oracle的Blob字段比long字段的性能要好,可以用来保存如图片之类的二进制数据。 
Oracle的BLOB字段由两部分组成:数据(值)和指向数据的指针(定位器)。尽管值与
 表自身一起存储,但是一个BLOB列并不包含值,仅有它的定位指针。为了使用大对象,程序必须声明定位器类型的本地变量。
当Oracle内部LOB被创建时,定位器被存放在列中,值被存放在LOB段中,LOB段是在数据库内部表的一部分。
因为Blob自身有一个cursor,当写入Blob字段必须使用指针(定位器)对Blob进行操作,因而在写入Blob之前,
 必须获得指针(定位器)才能进行写入
如何获得Blob的指针(定位器) :需要先插入一个empty的blob,这将创建一个blob的指针,然后再把这个empty
 的blob的指针查询出来,这样通过两步操作,就获得了blob的指针,可以真正的写入blob数据了。 
具体步骤:
1、插入空blob insert into javatest(name,content) values(?,empty_blob()); 


2、获得blob的cursor select content from javatest where name= ? for update; 
  注意:  须加for update,锁定该行,直至该行被修改完毕,保证不产生并发冲突。
3、利用 io,和获取到的cursor往数据库写数据流

案例:以下案例实现插入一张图片,和获取有一张图片的查询结果;
/*
 * 文件名:BlobTest.java
 * 版权:Copyright by www.huawei.com
 * 描述:
 * 修改人:Cuigaochong
 * 修改时间:2015-8-25
 * 跟踪单号:
 * 修改单号:
 * 修改内容:
 */

package com.jdbc.cgc.blob;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import oracle.sql.BLOB;

import org.junit.Test;

/**
 * <一句话功能简述> <功能详细描述>
 * 
 * @author 姓名 工号
 * @version [版本号, 2015-8-25]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class BlobTest
{
    
    /**
     * <一句话功能简述>测试方法,插入一条数据,数据中有一个列是Blob <功能详细描述>
     * 
     * @throws FileNotFoundException
     * @see [类、类#方法、类#成员]
     */
    @Test
    public void test00()
        throws FileNotFoundException
    {
        // 注意: 对于empty_blob()应放在SQL语句中直接赋值, 使用预置语句的方式赋值无法实现.
        String sql = "insert into t_emp13(first_name,salary,picture) values (?,?,Empty_BLOB())";
        // 查询Blob 注意进行 行锁定 后边的for update
        String sqlQuery = "select picture from t_emp13 where first_name = ? and salary = ? for update";
        updateBlob(sql, sqlQuery, "QQA122", 1233);
    }
    
    /**
     * <一句话功能简述>更新有blob的数据库表 <功能详细描述>
     * 
     * @param sqlInsert
     * @param sqlQuery
     * @param args
     * @see [类、类#方法、类#成员]
     */
    public void updateBlob(String sqlInsert, String sqlQuery, Object... args)
    {
        Connection conn = null;
        PreparedStatement prepareStatement = null;
        ResultSet rs = null;
        
        OutputStream os = null;
        FileInputStream fis = null;
        try
        {
            // 现在表中插入空的Blob
            conn = getConn();
            // 事物处理前,取消Connection的默认提交行为
            conn.setAutoCommit(false);
            prepareStatement = conn.prepareStatement(sqlInsert);
            
            for (int i = 0; i < args.length; i++)
            {
                prepareStatement.setObject(i + 1, args[i]);
            }
            prepareStatement.executeUpdate();
            
            BLOB blob = null;
            
            prepareStatement = conn.prepareStatement(sqlQuery);
            
            for (int i = 0; i < args.length; i++)
            {
                prepareStatement.setObject(i + 1, args[i]);
            }
            
            // prepareStatement.setString(1, "QQA");
            rs = prepareStatement.executeQuery();
            if (rs.next())
            {
                blob = (BLOB)rs.getBlob(1);
            }
            // 得到数据库的输出流
            os = blob.getBinaryOutputStream();
            // 得到要插入文件的输入流
            fis = new FileInputStream("Tulips.jpg");
            
            byte[] b = new byte[1024];
            int len;
            while (-1 != (len = fis.read(b)))
            {
                os.write(b, 0, len);
            }
            // 清空流的缓存
            os.flush();
            // 事物处理:如果事物处理成功则提交事物
            conn.commit();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            try
            {
                // 事物处理:如果出现异常 则在catch块中回滚事物
                conn.rollback();
            }
            catch (SQLException e1)
            {
                e1.printStackTrace();
            }
        }
        finally
        {
            if (null != fis)
            {
                try
                {
                    fis.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
            if (null != os)
            {
                try
                {
                    os.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
            
            releaseSource(prepareStatement, conn, null);
        }
    }
    
    /**
     * <一句话功能简述>测试方法,查询有blob的表 <功能详细描述>
     * 
     * @see [类、类#方法、类#成员]
     */
    @Test
    public void test01()
    {
        String sql = "select picture from t_emp13 where first_name = ?";
        queryBlob(sql, "QQA122");
    }
    
    /**
     * <一句话功能简述>查询有Blob的表 方法 <功能详细描述>
     * 
     * @param sql
     * @param args
     * @see [类、类#方法、类#成员]
     */
    public void queryBlob(String sql, Object... args)
    {
        Connection conn = null;
        PreparedStatement prepareStatement = null;
        ResultSet rs = null;
        
        FileOutputStream fos = null;
        InputStream is = null;
        
        try
        {
            conn = getConn();
            // 事物处理前,取消Connection的默认提交行为
            conn.setAutoCommit(false);
            prepareStatement = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++)
            {
                prepareStatement.setObject(i + 1, args[i]);
            }
            rs = prepareStatement.executeQuery();
            if (rs.next())
            {
                BLOB blob = (BLOB)rs.getBlob(1);
                is = blob.getBinaryStream();
                
                fos = new FileOutputStream(new File("test.png"));
                
                byte[] b = new byte[1024];
                int len;
                
                while (-1 != (len = is.read(b)))
                {
                    fos.write(b, 0, len);
                }
                fos.flush();
            }
            // 事物处理:如果事物处理成功则提交事物
            conn.commit();
            
        }
        catch (Exception e)
        {
            e.printStackTrace();
            try
            {
                // 事物处理:如果出现异常 则在catch块中回滚事物
                conn.rollback();
            }
            catch (SQLException e1)
            {
                e1.printStackTrace();
            }
        }
        finally
        {
            if (null != is)
            {
                try
                {
                    is.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
            
            if (null != fos)
            {
                try
                {
                    fos.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
            
            releaseSource(prepareStatement, conn, rs);
        }
    }
    
    /**
     * <一句话功能简述> 连接数据库 <功能详细描述>
     * 
     * @return
     * @throws Exception
     * @see [类、类#方法、类#成员]
     */
    public Connection getConn()
        throws Exception
    {
        String dirverName = null;
        String jdbcUrl = null;
        String user = null;
        String password = null;
        
        Properties propertoes = new Properties();
        InputStream is = getClass().getClassLoader().getResourceAsStream("jdbc.properties");
        propertoes.load(is);
        
        dirverName = propertoes.getProperty("driver");
        jdbcUrl = propertoes.getProperty("jdbcURL");
        user = propertoes.getProperty("user");
        password = propertoes.getProperty("password");
        
        Class.forName(dirverName);
        
        // 通过DriverManager的getConnection获取数据库连接
        Connection connection = DriverManager.getConnection(jdbcUrl, user, password);
        
        return connection;
    }
    
    /**
     * <一句话功能简述>释放数据库资源 <功能详细描述>
     * 
     * @param statement
     * @param conn
     * @param resultSet
     * @see [类、类#方法、类#成员]
     */
    public void releaseSource(Statement statement, Connection conn, ResultSet resultSet)
    {
        if (null != resultSet)
        {
            try
            {
                resultSet.close();
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
        }
        
        if (null != statement)
        {
            try
            {
                statement.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        if (null != conn)
        {
            try
            {
                conn.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 JDBCOracle 数据库写入 BLOB 类型数据的示例代码: ```java import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class WriteBlobToOracle { public static void main(String[] args) { // Oracle JDBC 驱动 String driver = "oracle.jdbc.driver.OracleDriver"; // 数据库连接信息 String url = "jdbc:oracle:thin:@localhost:1521:ORCL"; String user = "username"; String password = "password"; Connection conn = null; PreparedStatement pstmt = null; try { // 加载驱动程序 Class.forName(driver); // 获取数据库连接 conn = DriverManager.getConnection(url, user, password); // SQL 插入语句,参数使用 ? 占位符 String sql = "INSERT INTO blob_table (id, file_name, file_content) VALUES (?, ?, ?)"; // 创建 PreparedStatement 对象 pstmt = conn.prepareStatement(sql); // 设置参数 pstmt.setInt(1, 1); pstmt.setString(2, "test.txt"); // 读取文件内容到 InputStream 对象 File file = new File("test.txt"); InputStream is = new FileInputStream(file); // 设置 BLOB 类型参数 pstmt.setBinaryStream(3, is, (int) file.length()); // 执行 SQL 语句 int rowsAffected = pstmt.executeUpdate(); System.out.println(rowsAffected + " rows affected."); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭 PreparedStatement 和数据库连接 try { if (pstmt != null) pstmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } ``` 在上面的示例中,我们使用 `setBinaryStream()` 方法将文件内容写入 BLOB 字段。该方法需要三个参数: - 参数索引:指定 BLOB 参数的位置,从 1 开始计数。 - InputStream 对象:包含要写入 BLOB 字段的数据。 - BLOB 字段的长度:指定数据长度,使用文件的长度。 在插入数据之前,我们需要创建一个表来存储 BLOB 类型数据: ```sql CREATE TABLE blob_table ( id NUMBER(10) PRIMARY KEY, file_name VARCHAR2(50), file_content BLOB ); ``` 这个表包含三个字段: - `id`:表示唯一标识符。 - `file_name`:表示文件名。 - `file_content`:表示 BLOB 类型字段,用于存储文件内容。 最后,需要将文件 `test.txt` 放在项目根目录下,这个文件将被写入 BLOB 字段。如果需要写入其他文件,只需将文件名和路径更改为相应的值即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值