1

如果 XMLType 列存储为 CLOB(这是 11.2.0.1 的默认设置),我概述了针对 Oracle 11g(特别是 11.2.0.1)写入/读取 Oracle XMLType 列的解决方案。

参考答案:在 java spring hibernate 场景中使用 oracle XMLType

在 SQLDeveloper 中,如果您在表定义(表 DDL)中查看 SQL 选项卡,它会定义 11.2.0.1 中的 XML 列存储,如下所示:

 XMLTYPE COLUMN "ATTRIBUTE_XML2" STORE AS BASICFILE CLOB 

问题: 在 Oracle 11.2.0.2 中,XMLType 的默认存储类型是 Binary XML,出于性能原因,这是首选。它看起来像这样:

XMLTYPE COLUMN "ATTRIBUTE_XML2" STORE AS SECUREFILE BINARY XML

但是,一旦以这种方式存储,我引用的解决方案就不再适用于从数据库中将 XMLType 列作为 XML 读取。它从 xmlType.getStringVal() 返回一些垃圾,我假设它是 oracle 二进制编码的 XML。

终极问题 我无法从 oracle binxml 格式转换回有效的 XML 文档。

我已经在 Oracle概述的各种配置中尝试了 Oracle BinXMLProcessor、BinXMLStream、BinXMLDecoder 和 InfosetReader ,但它们似乎只是读取而不是解码它 - 所以它出错了。

nullSafeGet 中的基本示例(有关上下文,请参阅链接答案)。

xmlType = (XMLType) rs.getObject(names[0]);
BinXMLProcessor xp = BinXMLProcessorFactory.createProcessor();
BinXMLStream bstr = xp.createBinXMLStream(xmlType.getInputStream());
BinXMLDecoder xdecode = bstr.getDecoder();
InfosetReader reader = xdecode.getReader();

while (reader.hasNext() && i < 25) {
    i++;
    reader.next();
    logger.debug("1 v:" + reader.getValue() + ", s:" + reader.getStandalone() + ", type: " + reader.getEventType() + ", " + reader.getDataLength());
}

我尝试了类似的方法,将 xmlType.getInputStream() 替换为 xmlType.getBlobVal(178)、xmlType.getBytesValue(),但它们都抛出异常或返回垃圾数据。

嗯。

4

1 回答 1

0

找到了问题,与代码无关。

如参考答案中所述,Hibernate UserType 中正确的 nullSafeGet 是:

public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {

    if (logger.isTraceEnabled()) {
        logger.trace("  nullSafeSet: " + value + ", ps: " + st + ", index: " + index);
    }
    try {
        XMLType xmlType = null;
        if (value != null) {
            xmlType = XMLType.createXML(getOracleConnection(st.getConnection()), (String)value);
        }
        st.setObject(index, xmlType);
    } catch (Exception e) {
        throw new SQLException("Could not convert String to XML for storage: " + (String)value);
    }
}

问题:使用 SECUREFILE BINARY XML 列(不是 CLOB)时,您必须使用 xdb*.jar 的最新 (11.2.0.2+) 分发版,在本例中为 xdb6.jar (~257kb)。早期的 xdb*.jar(10.x 约为 136kb)仍然可以运行,即使在错误地解码 BINARY XML 时也不会抛出任何异常。

TL;DR从 Oracle 11gR2 (11.2.0.3) JDBC 驱动程序页面下载 xdb6.jar (~257kb)。旧的 xdb jars 会默默地失败,会让你难过。

于 2013-08-29T20:10:37.063 回答