如何使用 iBatis 从数据库中选择 BLOB 列
Posted
技术标签:
【中文标题】如何使用 iBatis 从数据库中选择 BLOB 列【英文标题】:How to Select a BLOB column from database using iBatis 【发布时间】:2012-08-21 17:17:03 【问题描述】:表的列之一是 BLOB 数据类型 (Oracle 10g)。我们通过 iBatis 执行了一个简单的选择查询来选择 BLOB 列并使用 Struts2 和 JSP 显示它。
iBatis xml 文件中的结果标签的 jdbctype 为 java.sql.Blob
<result property="uploadContent" column="uploadcontent" jdbctype="Blob"/>
我们应该提到 Blob 列的任何 typeHandler 类吗? 目前我们收到一个错误,说明列类型不匹配。
注意:选择此列并将其映射到具有 java.sql.Blob 类型属性的 java bean
【问题讨论】:
【参考方案1】:我认为您不能将本机 jdbctype
用于 Oracle 中的 LOB
类型和 iBatis
。解决方案是创建自定义typeHandler
来处理LOB
,然后像这样映射它-
<result property="aClassStringProperty" column="aClobColumn" typeHandler="com.path.to.my.ClobTypeHandler"/>
更多关于typeHandlerCallback
here的信息。
【讨论】:
【参考方案2】:不需要创建 typeHandler。对于 Oracle,jdbctype 是 BLOB
<result property="bytes" column="COLUMNBLOB" jdbcType="BLOB" />
假设“字节”为字节[]。
重要的是:在select sql中,必须这样设置jdbcType:
INSERT INTO X (COLUMNBLOB) VALUES #bytes:BLOB#
我注意到 Postgresql 的这个 jdbctype 是不同的。您必须设置:
<result property="bytes" column="COLUMNBLOB" jdbcType="BINARY" />
【讨论】:
【参考方案3】:我找到了处理这个问题的人here。
对于CLOB:
<result property="uploadContent" column="obfile" jdbctype="String" />
对于BLOB:
<result property="uploadContent" column="obfile" jdbctype="byte[]" />
我仍在寻找它与 C# 一起使用!
【讨论】:
【参考方案4】:我在使用 INSERT 时没有遇到问题,我在执行 blob 类型的 SELECT 时遇到了问题。我正在使用 Oracle 9i,这就是我所做的:
将 Oracle JDBC 驱动程序添加到您的项目中,您还需要 mybatis
依赖项。如果您使用的是 Maven:
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.3.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.3</version>
</dependency>
添加custom BaseTypeHandler for reading byte[] from Oracle BLOB 类:
@MappedTypes(byte[].class)
public class OracleBlobTypeHandler extends BaseTypeHandler<byte[]>
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, byte[] bytes, JdbcType jdbcType) throws SQLException
// see setBlobAsBytes method from https://jira.spring.io/secure/attachment/11851/OracleLobHandler.java
try
if (bytes != null)
//prepareLob
BLOB blob = BLOB.createTemporary(preparedStatement.getConnection(), true, BLOB.DURATION_SESSION);
//callback.populateLob
OutputStream os = blob.getBinaryOutputStream();
try
os.write(bytes);
catch (Exception e)
throw new SQLException(e);
finally
try
os.close();
catch (Exception e)
e.printStackTrace();//ignore
preparedStatement.setBlob(i, blob);
else
preparedStatement.setBlob(i, (Blob) null);
catch (Exception e)
throw new SQLException(e);
/** see getBlobAsBytes method from https://jira.spring.io/secure/attachment/11851/OracleLobHandler.java */
private byte[] getBlobAsBytes(BLOB blob) throws SQLException
//initializeResourcesBeforeRead
if(!blob.isTemporary())
blob.open(BLOB.MODE_READONLY);
//read
byte[] bytes = blob.getBytes(1L, (int)blob.length());
//releaseResourcesAfterRead
if(blob.isTemporary())
blob.freeTemporary();
else if(blob.isOpen())
blob.close();
return bytes;
@Override
public byte[] getNullableResult(ResultSet resultSet, String columnName) throws SQLException
try
//use a custom oracle.sql.BLOB
BLOB blob = (BLOB) resultSet.getBlob(columnName);
return getBlobAsBytes(blob);
catch (Exception e)
throw new SQLException(e);
@Override
public byte[] getNullableResult(ResultSet resultSet, int i) throws SQLException
try
//use a custom oracle.sql.BLOB
BLOB blob = (BLOB) resultSet.getBlob(i);
return getBlobAsBytes(blob);
catch (Exception e)
throw new SQLException(e);
@Override
public byte[] getNullableResult(CallableStatement callableStatement, int i) throws SQLException
try
//use a custom oracle.sql.BLOB
BLOB blob = (BLOB) callableStatement.getBlob(i);
return getBlobAsBytes(blob);
catch (Exception e)
throw new SQLException(e);
将类型处理程序包添加到 mybatis 配置中。如您所见,我使用的是spring-mybatis:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeHandlersPackage" value="package.where.customhandler.is" />
</bean>
然后,你可以从 Mybatis 的 Oracle BLOB 中读取 byte[]:
public class Bean
private byte[] file;
interface class Dao
@Select("select file from some_table where id=#id")
Bean getBean(@Param("id") String id);
我希望这会有所帮助。 这是对这个优秀答案的改编:这是对这个优秀答案的改编:https://***.com/a/27522590/2692914。
【讨论】:
以上是关于如何使用 iBatis 从数据库中选择 BLOB 列的主要内容,如果未能解决你的问题,请参考以下文章
如何从使用 Ionic 框架中的相机插件选择的视频文件 URI 创建 Blob?
如何从 blob 文件夹中选择 SQL Server 数据库的所有文件?