2014-01-26 38 views
2

我無法找出使用mybatis檢索BLOB的正確方法。使用mybatis檢索BLOB?

我發現了一些BLOB字段分配給對象中的byte []變量的例子。如果你知道所有的BLOB字段都很小,並且不介意將它們加載到內存中,我想這是可以的。但是,我有很多大的BLOB,我更願意將它們作爲流讀取。

我試着將BLOB分配給java.io.InputStream類型的屬性,但是這不起作用。錯誤消息是「找不到屬性inputStream的typehandler」(其中「inputStream」是InputStream屬性的名稱)。

任何人都可以在正確的方向指向我嗎?謝謝。

回答

0

由於沒有代表的InputStream沒有預定義的類型處理器,無論是

1)您可以通過延伸到BaseTypeHandler並覆蓋它的方法定義你自己的類型處理器。我不確定,但你可以返回一個InputStream對象。 http://mybatis.github.io/mybatis-3/configuration.html#typeHandlers

2)爲了處理clobs,我personnaly使用DBMS_LOB.SUBSTR(myClobColumn,size)。它比SUBSTR()更快,這要歸功於SO。 Performance of SUBSTR on CLOB

1

嗯,這裏是我如何做到這一點,但對於byte [],InputStream應該是直截了當的,但我認爲你需要保持連接打開(我不知道這是否可以完成MyBatis的)。

  1. 將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> 
    
  2. 添加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); 
         } 
        } 
    } 
    
  3. 添加類型處理器封裝MyBatis的配置。正如你所看到的,我使用的彈簧的MyBatis:

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
        <property name="dataSource" ref="dataSource" /> 
        <property name="typeHandlersPackage" value="package.where.customhandler.is" /> 
    </bean> 
    
  4. ,然後你可以從MyBatis的閱讀從Oracle BLOB的字節[]:

    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://stackoverflow.com/a/27522590/2692914