最近写的一个程序需要把数据库查询结果导成xml文件输出,于是当然想到了用webrowset的接口来实现,何况webrowset在jdk5.0中webrowset的实现已经是内置了的。
唯一担心的是具体的数据库驱动是否能够提供足够的支持来读取长字符串如ms sql server的 text字段 oracle的clob字段.于是写了个测试代码。发现情况还好只有某些驱动程序没有提供好的支持,换一个驱动就好了。
我进一步想看一看对与binary数据是否如jdk的文档所说的(A columnValue tag may contain either the stringData or binaryData tag, according to the SQL type that the XML value is mapping back to. The binaryData tag contains data in the Base64 encoding and is typically used for BLOB and CLOB type data.)会以Base64编码存储,然而换了几个驱动发现对与image/blob字段的输出是空空如也,什么也没有。<column-definition>
      <column-index>1</column-index>
      <auto-increment>false</auto-increment>
      <case-sensitive>true</case-sensitive>
      <currency>false</currency>
      <nullable>1</nullable>
      <signed>false</signed>
      <searchable>true</searchable>
      <column-display-size>16777215</column-display-size>
      <column-label>blobfield</column-label>
      <column-name>blobfield</column-name>
      <schema-name></schema-name>
      <column-precision>0</column-precision>
      <column-scale>0</column-scale>
      <table-name>tbl_in</table-name>
      <catalog-name>test1</catalog-name>
      <column-type>-4</column-type>  -----------SQLType -4 is 
      <column-type-name>BLOB</column-type-name>
    </column-definition><currentRow>
            <columnValue></columnValue>  -------什么值也没有。
</currentRow>最后只好把webrowset的实现代码反编译来看一看。webrowset的实现类为com.sun.rowset.WebRowSetImpl.class 它的输出xml文档的实现类为com.sun.rowset.internal.WebRowSetXmlWriter.class.这个类输出列值的方法为writeValue()
代码反编译后如下:
private void writeValue(int i, RowSet rowset)
        throws IOException
    {
        try
        {
            int j = rowset.getMetaData().getColumnType(i);
            switch(j)
            {
            case -7: 
            case 16: // '\020'
                boolean flag = rowset.getBoolean(i);
                if(rowset.wasNull())
                    writeNull();
                else
                    writeBoolean(flag);
                break;            case -4: ////
            case -3: ///  
            case -2: ///
                break;            case -6: 
            case 5: // '\005'
                short word0 = rowset.getShort(i);
                if(rowset.wasNull())
                    writeNull();
                else
                    writeShort(word0);
                break;            case 4: // '\004'
                int k = rowset.getInt(i);
                if(rowset.wasNull())
                    writeNull();
                else
                    writeInteger(rowset.getInt(i));
                break;            case -5: 
                long l = rowset.getLong(i);
                if(rowset.wasNull())
                    writeNull();
                else
                    writeLong(l);
                break;            case 6: // '\006'
            case 7: // '\007'
                float f = rowset.getFloat(i);
                if(rowset.wasNull())
                    writeNull();
                else
                    writeFloat(f);
                break;            case 8: // '\b'
                double d = rowset.getDouble(i);
                if(rowset.wasNull())
                    writeNull();
                else
                    writeDouble(d);
                break;            case 2: // '\002'
            case 3: // '\003'
                writeBigDecimal(rowset.getBigDecimal(i));
                break;            case 91: // '['
                Date date = rowset.getDate(i);
                if(rowset.wasNull())
                    writeNull();
                else
                    writeLong(date.getTime());
                break;            case 92: // '\\'
                Time time = rowset.getTime(i);
                if(rowset.wasNull())
                    writeNull();
                else
                    writeLong(time.getTime());
                break;            case 93: // ']'
                Timestamp timestamp = rowset.getTimestamp(i);
                if(rowset.wasNull())
                    writeNull();
                else
                    writeLong(timestamp.getTime());
                break;            case -1: 
            case 1: // '\001'
            case 12: // '\f'
                writeStringData(rowset.getString(i));
                break;            default:
                System.out.println(wrsWriterResBundle.handleGetObject     ("wrsxmlwriter.notproper").toString());
                break;
            }
        }
        catch(SQLException sqlexception)
        {
            throw new IOException(wrsWriterResBundle.handleGetObject("wrsxmlwriter.failedwrite").toString() + sqlexception.getMessage());
        }
    }上面代码我们可以注意到case -2,-3-4的情形均未做处理直接跳出。-2,-3,-4实际对应的是java.sql.Types 的BINARY、VARBINARY、LONGVARBINARY类型,也可以注意到在前面的xml片段中我一个名称为blobfield的blob字段(mysql数据库)被映射为-4,LONGVARBINARY类型。
然而它完全没有任何实现,不明白为何sun 没有去实现这个在规范中明确说明的要求。把数据库查询导成xml是一个很常规的应用,不知大家都是怎么来实现的?