使用MyBatis检索BLOB?

3
我在使用mybatis时遇到了检索BLOB的困难。
我发现了许多将BLOB字段赋值给对象中的一个byte[]变量的示例。如果你知道所有的BLOB字段都很小并且不介意将它们加载到内存中,那么这种方式也许是可以接受的。然而,我有很多大的BLOBs,我更喜欢把它们作为流读取。
我试图将BLOB分配给java.io.InputStream类型的属性,但这并没有起作用。错误消息是“找不到属性inputStream的类型处理程序”(其中“inputStream”是InputStream属性的名称)。
请问有谁能指点我一下正确的方向?谢谢。
3个回答

3

这是我处理byte[]的方法,对于InputStream应该也很直接,但我认为您需要保持连接开启(我不知道是否可以通过mybatis实现)。

  1. Add the Oracle JDBC driver to your project, you will need mybatis dependencies too. If you are using 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. Add the custom BaseTypeHandler for reading byte[] from Oracle BLOB class:

    @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. Add the type handlers package to mybatis configuration. As you can see, I am using spring-mybatis:

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="typeHandlersPackage" value="package.where.customhandler.is" />
    </bean>
    
  4. And then, you can read byte[] from Oracle BLOBs from 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


0

0

我以前遇到过这个问题。你只需要使用 "selectByExampleWithBLOBs"。

databaseStatementMapper.selectByExampleWithBLOBs(selectIn);

这是Mybatis的一个很好的特性,我已经遇到过:))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接