2013-06-11 5 views
2

Я пытаюсь получить содержимое столбца BLOB из базы данных Oracle с помощью mybatis. Существует таблица «Демо», которая содержит столбец «binfile» типа BLOB. Я хотел бы выбрать столбец BLOB и отобразить его как байтовый массив/необработанные двоичные данные. Я использую тонкий драйвер JDBC Oracle.Выберите столбец BLOB из Oracle DB с помощью mybatis

Запрос в mybatis картографа выглядит следующим образом:

<mapper namespace="Oracle" > 
... 
<select id="SelectBinary" resultType="hashmap"> 
    SELECT binfile from mpdemo.Demo 
    </select> 
</mapper> 

Если я сделаю это, то результат я получаю выглядит следующим образом:

BINFILE: "[email protected]" 

Если я это сделать:

<select id="SelectBinaryDup" resultType="hashmap"> 
    SELECT utl_raw.cast_to_varchar2(dbms_lob.substr(binfile)) from mpdemo.Demo 
</select> 

Я, очевидно, ошибаюсь, говоря, что необработанная переменная, обозначающая «PL/SQL: числовая или значение ошибки: необработанная переменная длина слишком долго g ', поскольку изображение намного превышает 100 kB, так как переменная VARCHAR2 в SQL может поддерживать только 2000 байт.

Есть ли решение для этого?

Я думал о записи сохраненного proc, который считывает блок столбца BLOB блоком и записывает вывод в файл. Но этот файл будет сохранен на сервере базы данных, и я не могу его восстановить.

ответ

2

Вы можете использовать BLOB непосредственно, сделайте import oracle.sql.BLOB;

Примеры:

BLOB blob = (BLOB)map.get("binfile"); 

//one way: as array 
byte[] bytes = blob.getBytes(1L, (int)blob.length()); 
System.out.println(new String(bytes)); //use for text data 
System.out.println(Arrays.toString(bytes)); 

//another way: as stream 
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("data.bin")); 
InputStream is = blob.binaryStreamValue(); 
int b = -1; 
while ((b = is.read()) != -1) { 
    bos.write(b); 
} 
bos.close(); 
+0

работает как очарование. благодаря! – codewarrior

0

вы пробовали отображения поля в jdbcType = LONGVARBINARY?

0

В моем случае мне пришлось реализовать custom BaseTypeHandler to support Oracle BLOB conversion to byte[] for 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. И затем, вы можете прочитать байт [] с Oracle BLOB-от Mybatis:

    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.

Смежные вопросы