2017-03-27 274 views
0

我可以从数据库中获取CLOB值,但如果价值更多的则是32K是越来越错误:如何在oracle11g中使用dbUtils获取CLOB列?

java.sql.SQLRecoverableException: Closed Connection 
        at oracle.sql.CLOB.getDBAccess(CLOB.java:1510) 
        at oracle.sql.CLOB.getSubString(CLOB.java:317) 

代码:

List<Map<String, Object>> resultListMap = null; 
try { 
                     
    new DbUtilsBeanListHandlerImpl(); 
    DbUtils.loadDriver(driver); 
    Properties connectionProperties = new Properties(); 
    connectionProperties.put("user", userName); 
    connectionProperties.put("password", password); 
    conn = DriverManager.getConnection(url, connectionProperties); 
    QueryRunner query = new QueryRunner(); 
          resultListMap = query.query(conn, dbQuery,  new MapListHandler());               

} catch (SQLException se) { 
    logger.error("SQLException to connect Database "+se.getMessage(), se); 
} finally { 
    DbUtils.closeQuietly(conn); 
} 

如何fetcha CLOB对象的更多然后32K使用dbUtils?

回答

1

问题不在于Apache Commons DbUtils的问题,而是涉及CLOB的常见问题。

正常情况下,当执行一个返回CLOB值的查询时,JDBC驱动程序在获取该行时将只加载部分CLOB值。在你的情况下,它似乎取得大约32K字符。对于小的CLOB值,这会节省数据库的往返行程以获取值。但是,如果值较大,驱动程序将不会获取整个值,并且需要对数据库进行后续调用以获取CLOB的其余部分。

就你而言,看起来这发生在你上面提供的代码运行之后。此时,数据库连接已关闭,因此读取其余CLOB数据为时已晚,因此您将得到一个关闭连接的例外情况。

更改此方法的一种方法是替换DbUtils使用的默认行处理器。以下版本预取CLOB值并将它们存储为字符串。据this answer,在CLOB值调用ResultSet.getString()就足以取整值:

import java.sql.Clob; 
import java.sql.ResultSet; 
import java.sql.ResultSetMetaData; 
import java.sql.SQLException; 
import java.util.HashMap; 
import java.util.Map; 

import org.apache.commons.dbutils.BasicRowProcessor; 

public class ClobAwareRowProcessor extends BasicRowProcessor { 

    @Override 
    public Map<String, Object> toMap(ResultSet resultSet) throws SQLException { 
     ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); 
     int columnCount = resultSetMetaData.getColumnCount(); 

     Map<String, Object> map = new HashMap<>(); 

     for (int index = 1; index <= columnCount; ++index) { 
      String columnName = resultSetMetaData.getColumnName(index); 
      Object object = resultSet.getObject(index); 
      if (object instanceof Clob) { 
       object = resultSet.getString(index); 
      } 

      map.put(columnName, object); 
     } 

     return map; 
    } 
} 

使用,具有new MapListHandler(new ClobAwareRowProcessor())更换new MapListHandler()

+0

完美的解决方案,我可以获取大的XML文件,我可以直接获得String对象而不是CLOB。非常感谢卢克伍德沃德。 –