`
wanglei6744
  • 浏览: 26173 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Oracle BLOB 存储 两三事

阅读更多

最近遇到好多需要存储Oracle BLOB 需求。 众所周知,BLOB 是用来存储图片、PDF、等大数据对象的。由于公司的需要我们所有的数据库操作都要使用存储过程来操作。所以首先先贴上一个BLOB存储的存储过程供大家参考:

create or replace
procedure NDSSP_backup_fund (fund_id_in in varchar2 ,selector_in in varchar2,
time_in in timestamp,blob_in in BLOB) 
  is
    key number;
    blob_tmp blob;
  begin
    delete from fund_backup bf where bf.selector = selector_in and bf.fund_id = fund_id_in;
    select fund_backup_seq.nextval into key from dual;
    insert into fund_backup values(key,selector_in,fund_id_in,empty_blob(),time_in);
    select content into  blob_tmp from fund_backup where id = key for update;
    dbms_lob.copy(blob_tmp, blob_in, dbms_lob.getLength(blob_in));
  end NDSSP_backup_fund;

  大家只要关注BLOB存储的部分就好了,其他的部分都可以忽略。正如大家所看到的,我们想要调用这个存储过程,必须要传递一个BLOB 对象。BLOB对象比较特殊,我们不能直接去new它。我们必须要调用Oracle 驱动提供的 createTemporary方法,具体代码如下:

    private BLOB transformObj2Blob(Object obj, Connection conn)
    {
	OutputStream os = null;
	ObjectOutputStream oos = null;
	BLOB blob = null;
	try
	{
	    blob = BLOB.createTemporary(conn, true, BLOB.DURATION_SESSION);
	    os = blob.setBinaryStream(0l);
	    oos = new ObjectOutputStream(os);
	    oos.writeObject(obj);
	    oos.flush();
	    os.flush();
	}
	catch (SQLException e)
	{
	    e.printStackTrace();
	}
	catch (IOException e)
	{
	    e.printStackTrace();
	}
	finally
	{

	    try
	    {
		if (oos != null)
		    oos.close();
	    }
	    catch (IOException e)
	    {
		LogUtil.debug(e);
	    }
	}

	return blob;
    }

 这里又引入了一个新的问题: connection , 大家可能觉得 connection 能有什么问题 就是数据库连接嘛,没错它就是数据库连接,但是在这个方法中conn 会被强制转化成 oracle.jdbc.driver.OracleDriver 这就意味着我们传进去的Connection 必须原始的没有经过任何包装的connection。但是在这个连接池充斥的年代,我们很难拿到原始的Connection了我们拿到的都是经过包装的Connection了。所以一般第一次用这个方法的人都很有可能遇到CastException 。如何拿到原始的Connection不同的连接池有不同的方法:

1、Tomcat 连接池(dbcp 如此类似):

if(connecion instanceof org.apache.tomcat.dbcp.dbcp.DelegatingConnection)
		{
			realConn =  ((org.apache.tomcat.dbcp.dbcp.DelegatingConnection) connecion)
				.getInnermostDelegate();
			return realConn;
		}

 2、Webphere 连接池:

if(connecion instanceof com.ibm.ws.rsadapter.jdbc.WSJdbcConnection)
		{
			realConn = (Connection) com.ibm.ws.rsadapter.jdbc.WSJdbcUtil.
			getNativeConnection(
				(com.ibm.ws.rsadapter.jdbc.WSJdbcConnection)connecion);
			return realConn;
		}
 

 3、MyBaits 连接池(Pooled 方式):

realConn = PooledDataSource.unwrapConnection(connecion);

 

其他的连接池需要自己去探索了。如果你认为到此这篇文章已经结束了那你就错了。对于我这种用Mybatis的悲催男来说这远远没有结束。大家请看这段代码:

 try {
      final Environment environment = configuration.getEnvironment();
      final DataSource dataSource = getDataSourceFromEnvironment(environment);
      TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      Connection connection = dataSource.getConnection();
      if (level != null) {
        connection.setTransactionIsolation(level.getLevel());
      }
      connection = wrapConnection(connection);
      Transaction tx = transactionFactory.newTransaction(connection, autoCommit);
      Executor executor = configuration.newExecutor(tx, execType);
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (SQLException e) {
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }


 private Connection wrapConnection(Connection connection) {
    if (log.isDebugEnabled()) {
      return ConnectionLogger.newInstance(connection);
    } else {
      return connection;
    }
  }

让我们再来看看ConnectionLogger.newInstance(connection) 方法:

public static Connection newInstance(Connection conn) {
    InvocationHandler handler = new ConnectionLogger(conn);
    ClassLoader cl = Connection.class.getClassLoader();
    return (Connection) Proxy.newProxyInstance(cl, new Class[]{Connection.class}, handler);
  }

  看到原因了吧,只要你开启了Log 到debug 级别(isDebugEnabled 还没研究 不同环境表现不同 大家见谅),MyBatis tm的把所有 connection 动态代理了一遍。只要你通过session.getConnection 方法拿connection,不管你有没有用连接池用的是啥连接池,你拿到的都不一定是原始的connection。纠结的Mybatis啊。看到这里我很有改源代码的冲动啊。所以我们不能通过session直接拿connection了,我们必须先拿到数据源然后直接从数据源拿connection然后调用上边说的转化方式拿原始的connection:

connecion=session.getConfiguration().getEnvironment().getDataSource().getConnection();

 

到此这篇文章结束了 希望能够给同学们一点帮助……

我的微薄:http://weibo.com/lei6744

 

分享到:
评论
2 楼 grayliu 2011-07-19  
good,加关注。。。。
1 楼 yixiugg 2011-07-19  
很有帮助,顶,re,赞

相关推荐

    【Oracle BLOB】存储的图片批量导出到文件夹

    使用PL/SQL脚本将Oracle的Blob字段中存储的图片批量导出到文件夹,可在文件夹中直接查看。

    oracle blob转文件读取

    在Oracle数据库中,BLOB是一种特殊的数据类型,用于存储大量二进制数据。 #### 二、C#中的Oracle Blob操作 在C#中,可以通过`System.Data.OracleClient`命名空间下的类来实现对Oracle数据库的操作。具体到Blob类型...

    oracle blob图片导出工具

    批量导出oracle bolb图片到本地文件

    oracle中的BLOB(照片)转换到mysql中

    Oracle数据库系统支持多种复杂的数据类型,其中包括BLOB(Binary Large Object),用于存储非结构化的大数据,如图片、音频或视频文件。而MySQL同样提供了BLOB类型,用于相似的用途。本篇将详细讲解如何在Oracle与...

    oracle Blob转换Clob

    - **数据类型**:Blob存储的是二进制数据,而Clob存储的是字符数据。 - **应用场景**:Blob适用于图片、视频等多媒体文件的存储;Clob则更适用于文档、文章等文本数据的存储。 - **处理方式**:Blob数据通常需要通过...

    oracle blob 字段 读写 delphi

    Oracle数据库中的BLOB(Binary Large Object)字段是用来存储大量二进制数据的,例如图片、文档或音频文件。在Delphi编程环境中,处理这类数据时需要掌握特定的API调用和方法。本篇文章将深入探讨如何在Delphi中对...

    Oracle blob字段上传下载

    Oracle数据库支持Blob类型,允许用户在数据库中直接存储和管理这些大型文件。本文将详细介绍如何在Oracle数据库中实现Blob字段的上传和下载操作。 #### 二、Blob字段上传 Blob字段的上传通常涉及到以下几个步骤: ...

    批量导出ORACLE数据库BLOB字段生成图片

    Oracle数据库在存储大对象(BLOB)数据时,提供了高效且灵活的方式,使得二进制数据如图片、文档等能够安全地保存在数据库中。批量导出Oracle数据库中的BLOB字段生成图片,是一项常见的需求,尤其对于那些需要将...

    ORACLE中BLOB字段导入到SQL SERVER中的IMAGE字段

    在ORACLE数据库中,BLOB是一种用于存储大量二进制数据的数据类型,如图片、音频或视频文件。而在SQL SERVER中,IMAGE字段同样用于存储大块的二进制数据,但在SQL SERVER 2005及以后的版本中已被废弃,取而代之的是...

    oracle查询blob字段照片(jpeg) 像素大小sql

    在Oracle数据库中,Blob是一种用来存储二进制数据的数据类型,比如图像、音频或视频文件等。本篇文章将详细介绍如何通过SQL查询语句获取存储在Blob字段中的JPEG格式照片的像素大小。 ### 1. 了解Blob数据类型 在...

    批量导出ORACLE数据库BLOB字段生成文件

    Oracle数据库是全球广泛使用的大型企业级数据库管理系统,它支持多种数据类型,包括BLOB(Binary Large Object),用于存储图像、文档等二进制大对象。本教程将详细讲解如何批量导出Oracle数据库中的BLOB字段并生成...

    java中读取ORACLE中BLOB字段存储的图片

    ### Java中读取Oracle数据库BLOB字段存储的图片方法详解 #### 一、背景与目的 在实际的应用开发过程中,经常会有将图片等二进制数据存入数据库的需求。Oracle数据库支持通过BLOB(Binary Large Object)类型来存储...

    oracle(blob转换为clob)

    在Oracle数据库环境中,数据类型BLOB(Binary Large Object)用于存储大量的二进制数据,如图像、音频或视频文件,而CLOB(Character Large Object)则用于存储大量文本数据。在某些情况下,可能需要将BLOB类型的...

    jdbc 操作oracle blob数据

    jdbc 操作oracle blob数据jdbc 操作oracle blob数据jdbc 操作oracle blob数据jdbc 操作oracle blob数据jdbc 操作oracle blob数据jdbc 操作oracle blob数据jdbc 操作oracle blob数据jdbc 操作oracle blob数据jdbc ...

    C#访问oracle数据库类,带blob字段读写

    Blob字段用于存储大对象,如图片、视频或二进制文件。在C#中,我们使用`OracleDbType.Blob`类型来处理Blob字段。读取Blob字段时,可以创建一个`OracleBinary`对象,然后使用`GetValue`方法获取Blob数据。写入Blob...

    文件上传至oracle blob字段的java实现

    指定文件夹下的所有文件上传至oracle的blob字段,java实现

    java对oracle数据库中blob字段的处理

    BLOB字段主要用于存储大量的二进制数据,如图像、音频、视频或任何其他非文本格式的数据。Java对Oracle数据库中BLOB字段的处理涉及多个层面,包括读取、写入、更新以及跨数据库操作等。 ### Java处理Oracle BLOB...

    Python如何操作Oracle的Blob字段

    Python如何操作Oracle的Blob字段,

    oracle Blob

    Oracle中的Blob类型是一种用于存储大型二进制对象的数据类型,如图像、音频或视频文件等。Blob相比于long字段,提供了更好的性能,特别是处理大量非结构化数据时。Blob的使用涉及多个步骤,包括创建、插入、读取和...

    blob_oracle.rar_blob_blob oracle_c++ oracle blob_oracle_oracle

    在Oracle数据库系统中,BLOB(Binary Large Object)是一种数据类型,用于存储大量的二进制数据,如图像、音频文件或任何非结构化的文本数据。本教程将详细讲解如何使用C++与Oracle数据库进行交互,特别是针对BLOB...

Global site tag (gtag.js) - Google Analytics