JDBCでのXML型データの取得
DB2のXML型のデータをJDBCで取得する方法を探ってみる。
JDK 5.0 (JDBC 3.0)の場合
まず、getObjectして、実装されているインタフェースを調べてみる。
String queryStr = "SELECT XMLDOCUMENT(XMLELEMENT(NAME \"res\", T.VAL)) AS DATA FROM TABLE(VALUES('気まぐれ日記')) AS T(VAL)"; PreparedStatement pstmt = conn.prepareStatement(queryStr); ResultSet result = pstmt.executeQuery(); while (result.next()) { Object obj = result.getObject(1); final Class target = obj.getClass(); new Runnable() { public void run() { dump(target); } void dump(Class cls) { if (cls != null) { print(cls.getInterfaces()); dump(cls.getSuperclass()); } } void print(Class[] cls) { for (Class c : cls) { System.out.println(c.getName()); print(c.getInterfaces()); } } }.run(); }
すると、インタフェース com.ibm.db2.jcc.DB2Xml を実装していることがわかる。
ということで、こんな感じになる。
String queryStr = "SELECT XMLDOCUMENT(XMLELEMENT(NAME \"res\", T.VAL)) AS DATA FROM TABLE(VALUES('気まぐれ日記')) AS T(VAL)"; PreparedStatement pstmt = conn.prepareStatement(queryStr); ResultSet result = pstmt.executeQuery(); while (result.next()) { com.ibm.db2.jcc.DB2Xml data = (com.ibm.db2.jcc.DB2Xml) result.getObject(1); System.out.println("### DB2Xml.getDB2String: " + data.getDB2String()); System.out.println("### DB2Xml.getDB2XmlString: " + data.getDB2XmlString()); System.out.println("### DB2Xml.toString: " + data.toString()); // InputStream, Reader系のメソッドもあるが、面倒なので省略(ぉ System.out.println("%%% ResultSet.getString: " + result.getString(1)); }
得られる結果はこんな感じ。
### DB2Xml.getDB2String: <res>気まぐれ日記</res> ### DB2Xml.getDB2XmlString: <?xml version="1.0" encoding="ISO-10646-UCS-2"?><res>気まぐれ日記</res> ### DB2Xml.toString: com.ibm.db2.jcc.b.yd@a0dcd9 %%% ResultSet.getString: <res>気まぐれ日記</res>
まぁ、普通はドライバ依存のコードは書きたくないわけで、ResultSetのInputStreamやReaderを取得するメソッドか、getStringを使うくらいしか手段はなさそう。
JDK 6 (JDBC 4.0)の場合
APIドキュメントを見てみると、java.sql.SQLXML というインタフェースが追加されている。
DB2も、v9.5では db2jcc4.jar というJARファイルが新たに追加されており、JDBC 4.0対応のものらしい。
ということで、JDK 5.0の場合と同じことを試してみると、実装しているインタフェースは以下。
JDBC 4.0対応の方だと、DB2Xmlインタフェースはちゃんとdeprecatedになっている。
同様にデータを取得し、表示させてみる。
String queryStr = "SELECT XMLDOCUMENT(XMLELEMENT(NAME \"res\", T.VAL)) AS DATA FROM TABLE(VALUES('気まぐれ日記')) AS T(VAL)"; PreparedStatement pstmt = conn.prepareStatement(queryStr); ResultSet result = pstmt.executeQuery(); while (result.next()) { com.ibm.db2.jcc.DB2Xml data = (com.ibm.db2.jcc.DB2Xml) result.getObject(1); System.out.println("### DB2Xml.getDB2String: " + data.getDB2String()); System.out.println("### DB2Xml.getDB2XmlString: " + data.getDB2XmlString()); System.out.println("### DB2Xml.toString: " + data.toString()); // InputStream, Reader系のメソッドもあるが、面倒なので省略(ぉ java.sql.SQLXML data2 = result.getSQLXML(1); System.out.println("$$$ SQLXML.getString: " + data2.getString()); System.out.println("$$$ SQLXML.toString: " + data2.toString()); // InputStream, Reader系のメソッドもあるが、面倒なので省略(ぉぉ System.out.println("%%% ResultSet.getString: " + result.getString(1)); }
結果はこんな感じ。
### DB2Xml.getDB2String: <res>気まぐれ日記</res> ### DB2Xml.getDB2XmlString: <?xml version="1.0" encoding="ISO-10646-UCS-2"?><res>気まぐれ日記</res> ### DB2Xml.toString: com.ibm.db2.jcc.a.ae@b753f8 $$$ SQLXML.getString: <res>気まぐれ日記</res> $$$ SQLXML.toString: com.ibm.db2.jcc.a.ae@b753f8 %%% ResultSet.getString: <res>気まぐれ日記</res>
まぁ、でも、今現在の開発のターゲットがJDK 5.0ベースだったりするので‥orz