最近遇到好多需要存储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
分享到:
相关推荐
C# oracle blob类型 读入与保存
Oracle blob字段上传下载 Oracle blob字段上传下载Oracle blob字段上传下载 Oracle blob字段上传下载
批量导出oracle bolb图片到本地文件
oracle Blob转换Clob
使用PL/SQL脚本将Oracle的Blob字段中存储的图片批量导出到文件夹,可在文件夹中直接查看。
很多朋友在操作oracle数据库的clob,blob字段时不知道怎么插入和使用,这里提供读写范例。
oracle Blob Clob 大数处理 代码 文件上传 下载
从oracle中的BLOB类型字段中取出照片,转存到mysql数据库中。思路是现将oracle中的照片存储在本地文件夹,在将本地图片上传到mysql中。
java中读取ORACLE中BLOB字段存储的图片
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 ...
只需要安装oracle client在本地,然后配置好tns,输入连接名,用户名,密码,数据表的名称,文件名数据列名以及blob数据列名,就可以批量导出ORACLE数据库BLOB字段生成图片
该程序可将ORACLE中BLOB字段导入到SQL SERVER中的IMAGE字段,方便快捷。
oracle查询blob字段照片(jpeg) 像素大小sql
UTL_RAW.CAST_TO_VARCHAR2
Oracle导出Clob,Blob等大字段工具,自己写的工具,方便大家下载使用
oracle中用来存储大数据的BLOB(图片,文本,文件等)的 读写与复制方法
C#访问oracle数据库类 1、执行非查询命令 2、执行查询命令 3、带blob字段读写
oracle中对blob字段的处理方法,包括增加,删除,修改,更新等操作。
视频第六部分共七部分 下载全才可以解压 博文链接:https://dlivan.iteye.com/blog/116258