gpt4 book ai didi

java - 如何在oracle11g中使用dbUtils获取CLOB列?

转载 作者:行者123 更新时间:2023-12-02 02:56:12 25 4
gpt4 key购买 nike

我可以从数据库中获取 CLOB 值,但如果值大于 32k,则会出现错误:

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);
}

如何使用 dbUtils 获取超过 32k 的 CLOB 对象?

最佳答案

这个问题并不是 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 MapListHandler(new ClobAwareRowProcessor())

关于java - 如何在oracle11g中使用dbUtils获取CLOB列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43046722/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com