JDBC獲取數據庫表字段信息


隨着項目的需要,對於數據庫支持要求越多越好,最好是Generic JDBC Connection。為此,筆者要求項目程序內只允許使用JDBC接口。在此條件下如何獲取表的字段信息?有哪幾種方式?都適用嗎?

字段信息     

       字段在表里就是一個Column,關於ColumnJDBC里面有20多個參數來描述它,稱為元數據,Metadata。包括:

1.                TABLE_CAT String => table catalog (may be null)

2.                TABLE_SCHEM String => table schema (may be null)

3.                TABLE_NAME String => table name

4.                COLUMN_NAME String => column name

5.                DATA_TYPE int => SQL type from java.sql.Types

6.                TYPE_NAME String => Data source dependent type name, for a UDT the type name is fully qualified

7.                COLUMN_SIZE int => column size.

8.                BUFFER_LENGTH is not used.

9.                DECIMAL_DIGITS int => the number of fractional digits. Null is returned for data types where DECIMAL_DIGITS is not applicable.

10.            NUM_PREC_RADIX int => Radix (typically either 10 or 2)

11.            NULLABLE int => is NULL allowed.

o                                            columnNoNulls - might not allow NULL values

o                                            columnNullable - definitely allows NULL values

o                                            columnNullableUnknown - nullability unknown

12.            REMARKS String => comment describing column (may be null)

13.            COLUMN_DEF String => default value for the column, which should be interpreted as a string when the value is enclosed in single quotes (may be null)

14.            ……

    通常關注的是COLUMN_NAME、DATA_TYPE、TYPE_NAME等。

getColumns()獲取字段信息

       JDBC里有DatabaseMetadata接口,通過它可以拿到數據庫的元數據,也就是數據庫的相關描述信息。果然,getColumns()就可以拿到表所有的字段信息:

Connection conn = dbms.getConnection();

DatabaseMetaData dmd = conn.getMetaData();

ResultSet rs = dmd.getColumns( null, “%”, strTableName, “%”);

Whiel( rs.next() )

{

    String strFieldName = Rs.getString( 4 );

    String strFieldType = Rs.getString( 5 );

}

       這種方式的特點是不需要去訪問表內數據,看上去也很簡潔。在mysql, postgresql中都很順利,但很可惜,在連Oracle(JDBC 10.2.0.4)的時候,rs.next()false了。查看Oracle JDBCdoc,這也是支持的該接口的,並沒有任何特別的說明。那奇怪了。再在OracleJDBC的文檔上看到該版本Bug列表

The following table lists the JDBC bugs addressed in this patch set:

5892966

No columns from getColumns() when includeSynonyms=true

原來這里有個特殊的,當includeSysonyms設為true, getColumns是沒有返回的。這個OracleOracle就有點不太符合JDBC的標准了。Oracle文檔有這一段話:

By default, the getColumns method does not retrieve information about the columns if a synonym is specified. To enable the retrieval of information if a synonym is specified, you must call the setIncludeSynonyms method on the connection as follows:

( (oracle.jdbc.driver.OracleConnection)conn ).setIncludeSynonyms(true)

This will cause all subsequent getColumns method call on the connection to include synonyms. This is similar to setRemarksReporting. Alternatively, you can set the includeSynonymsconnection property. This is similar to the remarksReporting connection property.

這段話基本上也是講了這個問題。針對Oracle特別的設置這是項目所不允許的,怎么辦?

 

ResultSetMetaData獲取字段信息

除了直接查看數據庫元數據,還可以通過訪問表數據來獲取記錄集元數據。利用ResultMetaData來獲取字段信息是比較好的方式,無論表內是否有數據都可返回字段信息,同時測試發現在實驗數據庫當中都是可行的。

       Connection conn = dbms.getConnection();

       DatabaseMetaData dmd = conn.getMetaData();

      

       Statement st = conn.createStatement();

       String sql = "SELECT * FROM "+table;

       ResultSet rs = st.executeQuery(sql);

       ResultSetMetaData rsmd = rs.getMetaData();

             

       forint i=1; i<=rsmd.getColumnCount(); i++ )

       {

           String field = rsmd.getColumnName(i);

           fields.add( field );

          

           String type = Integer.toString( rsmd.getColumnType(i) ); //5--DATA_TYPE int => SQL type from java.sql.Types

           SqlType sqlT = SqlMapper.mapId( type );

           type = sqlT.sName;

           fieldTypes.add( type );

       }

 

 

注:

①測試數據庫:Mckoi 1.0.3, MySQL 5.0, PostgreSQL 8.3, Oracle 10g r2, Oracle 10g XE


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM