1. 程式人生 > >JDBC元資料操作-- DatabaseMetaData介面詳解

JDBC元資料操作-- DatabaseMetaData介面詳解

  1. package com.util;  
  2. import java.sql.CallableStatement;  
  3. import java.sql.Connection;  
  4. import java.sql.DatabaseMetaData;  
  5. import java.sql.DriverManager;  
  6. import java.sql.PreparedStatement;  
  7. import java.sql.ResultSet;  
  8. import java.sql.SQLException;  
  9. import java.sql.Statement;  
  10. import oracle.jdbc.driver.OracleConnection;  
  11. /** 
  12.  * @Description: JDBC操作元資料示例-- DatabaseMetaData介面 
  13.  * @CreateTime: 2014-1-19 下午9:46:44 
  14.  * @author: chenzw  
  15.  * @version V1.0 
  16.  */  
  17. public class JdbcUtil {  
  18.     //獲得驅動    
  19.     private static String DRIVER = "oracle.jdbc.driver.OracleDriver";    
  20.     //獲得url    
  21.     private static String URL = "jdbc:oracle:thin:@localhost:test";    
  22.     //獲得連線資料庫的使用者名稱    
  23.     private static String USER = "root";    
  24.     //獲得連線資料庫的密碼    
  25.     private static String PASS = "root";    
  26.     static {    
  27.         try {     
  28.             //初始化JDBC驅動並讓驅動載入到jvm中    
  29.             Class.forName(DRIVER);    
  30.         } catch (ClassNotFoundException e) {    
  31.             e.printStackTrace();    
  32.         }    
  33.     }    
  34.     public static Connection getConnection(){    
  35.         Connection conn = null;    
  36.         try {     
  37.             //連線資料庫    
  38.            /* 
  39.             * 設定可獲取REMARK備註資訊 
  40.            Properties props =new Properties(); 
  41.            props.put("remarksReporting","true"); 
  42.            props.put("user", USER); 
  43.            props.put("password", PASS); 
  44.            conn =DriverManager.getConnection(URL,props);*/  
  45.             conn = DriverManager.getConnection(URL,USER,PASS);    
  46.             conn.setAutoCommit(true);  
  47.         } catch (SQLException e) {    
  48.             e.printStackTrace();    
  49.         }    
  50.         return conn;    
  51.     }    
  52.     //關閉連線  
  53.     public static void close(Object o){    
  54.         if (o == null){    
  55.             return;    
  56.         }    
  57.         if (o instanceof ResultSet){    
  58.             try {    
  59.                 ((ResultSet)o).close();    
  60.             } catch (SQLException e) {    
  61.                 e.printStackTrace();    
  62.             }    
  63.         } else if(o instanceof Statement){    
  64.             try {    
  65.                 ((Statement)o).close();    
  66.             } catch (SQLException e) {    
  67.                 e.printStackTrace();    
  68.             }    
  69.         } else if (o instanceof Connection){    
  70.             Connection c = (Connection)o;    
  71.             try {    
  72.                 if (!c.isClosed()){    
  73.                     c.close();    
  74.                 }    
  75.             } catch (SQLException e) {    
  76.                 e.printStackTrace();    
  77.             }    
  78.         }      
  79.     }    
  80.     public static void close(ResultSet rs, Statement stmt,     
  81.             Connection conn){    
  82.         close(rs);    
  83.         close(stmt);    
  84.         close(conn);    
  85.     }    
  86.     public static void close(ResultSet rs,     
  87.             Connection conn){    
  88.         close(rs);     
  89.         close(conn);    
  90.     }    
  91.     /** 
  92.      * @Description: 獲取資料庫相關資訊 
  93.      * @author: chenzw  
  94.      * @CreateTime: 2014-1-27 下午5:09:12  
  95.      * @throws 
  96.      */  
  97.     public static void getDataBaseInfo() {    
  98.         Connection conn =  getConnection();  
  99.         ResultSet rs = null;  
  100.         try{    
  101.              DatabaseMetaData dbmd = conn.getMetaData();  
  102.              System.out.println("資料庫已知的使用者: "+ dbmd.getUserName());      
  103.              System.out.println("資料庫的系統函式的逗號分隔列表: "+ dbmd.getSystemFunctions());      
  104.              System.out.println("資料庫的時間和日期函式的逗號分隔列表: "+ dbmd.getTimeDateFunctions());      
  105.              System.out.println("資料庫的字串函式的逗號分隔列表: "+ dbmd.getStringFunctions());      
  106.              System.out.println("資料庫供應商用於 'schema' 的首選術語: "+ dbmd.getSchemaTerm());      
  107.              System.out.println("資料庫URL: " + dbmd.getURL());      
  108.              System.out.println("是否允許只讀:" + dbmd.isReadOnly());      
  109.              System.out.println("資料庫的產品名稱:" + dbmd.getDatabaseProductName());      
  110.              System.out.println("資料庫的版本:" + dbmd.getDatabaseProductVersion());      
  111.              System.out.println("驅動程式的名稱:" + dbmd.getDriverName());      
  112.              System.out.println("驅動程式的版本:" + dbmd.getDriverVersion());    
  113.              System.out.println("資料庫中使用的表型別");      
  114.              rs = dbmd.getTableTypes();      
  115.              while (rs.next()) {      
  116.                  System.out.println(rs.getString("TABLE_TYPE"));      
  117.              }      
  118.         }catch (SQLException e){    
  119.             e.printStackTrace();    
  120.         } finally{  
  121.             JdbcUtil.close(rs,conn);  
  122.         }   
  123.     }   
  124.     /** 
  125.      * @Description:獲得資料庫中所有Schemas(對應於oracle中的Tablespace) 
  126.      * @author: chenzw  
  127.      * @CreateTime: 2014-1-27 下午5:10:35  
  128.      * @throws 
  129.      */  
  130.     public static void getSchemasInfo(){    
  131.         Connection conn =  getConnection();  
  132.         ResultSet rs = null;  
  133.         try{    
  134.             DatabaseMetaData dbmd = conn.getMetaData();  
  135.             rs = dbmd.getSchemas();     
  136.             while (rs.next()){       
  137.                 String tableSchem = rs.getString("TABLE_SCHEM");   
  138.                 System.out.println(tableSchem);       
  139.             }       
  140.         } catch (SQLException e){    
  141.             e.printStackTrace();       
  142.         } finally{  
  143.             JdbcUtil.close(rs,conn);  
  144.         }    
  145.     }    
  146.     /** 
  147.      * @Description: 獲取資料庫中所有的表資訊 
  148.      * @author: chenzw  
  149.      * @CreateTime: 2014-1-27 下午5:08:28  
  150.      * @throws 
  151.      */  
  152.     public static void getTablesList() {    
  153.         Connection conn =  getConnection();  
  154.         ResultSet rs = null;  
  155.         try {    
  156.             /** 
  157.              * 設定連線屬性,使得可獲取到表的REMARK(備註) 
  158.              */  
  159.             ((OracleConnection)conn).setRemarksReporting(true);   
  160.             DatabaseMetaData dbmd = conn.getMetaData();  
  161.             String[] types = { "TABLE" };    
  162.             rs = dbmd.getTables(null, null, "%", types);    
  163.             while (rs.next()) {    
  164.                 String tableName = rs.getString("TABLE_NAME");  //表名    
  165.                 String tableType = rs.getString("TABLE_TYPE");  //表型別    
  166.                 String remarks = rs.getString("REMARKS");       //表備註    
  167.                 System.out.println(tableName + " - " + tableType + " - " + remarks);    
  168.             }    
  169.         } catch (SQLException e) {    
  170.             e.printStackTrace();    
  171.         } finally{  
  172.             JdbcUtil.close(rs,conn);  
  173.         }   
  174.     }    
  175.     /** 
  176.      * @Description: 獲取某表資訊 
  177.      * @author: chenzw  
  178.      * @CreateTime: 2014-1-27 下午3:26:30  
  179.      * @throws 
  180.      */  
  181.     public static void getTablesInfo(){  
  182.         Connection conn =  getConnection();  
  183.         ResultSet rs = null;  
  184.         try {  
  185.             /** 
  186.              * 設定連線屬性,使得可獲取到表的REMARK(備註) 
  187.              */  
  188.             ((OracleConnection)conn).setRemarksReporting(true);   
  189.             DatabaseMetaData dbmd = conn.getMetaData();  
  190.             /** 
  191.              * 獲取給定類別中使用的表的描述。 
  192.              * 方法原型:ResultSet getTables(String catalog,String schemaPattern,String tableNamePattern,String[] types); 
  193.              * catalog - 表所在的類別名稱;""表示獲取沒有類別的列,null表示獲取所有類別的列。 
  194.              * schema - 表所在的模式名稱(oracle中對應於Tablespace);""表示獲取沒有模式的列,null標識獲取所有模式的列; 可包含單字元萬用字元("_"),或多字元萬用字元("%"); 
  195.              * tableNamePattern - 表名稱;可包含單字元萬用字元("_"),或多字元萬用字元("%"); 
  196.              * types - 表型別陣列; "TABLE"、"VIEW"、"SYSTEM TABLE"、"GLOBAL TEMPORARY"、"LOCAL TEMPORARY"、"ALIAS" 和 "SYNONYM";null表示包含所有的表型別;可包含單字元萬用字元("_"),或多字元萬用字元("%");  
  197.              */  
  198.             rs = dbmd.getTables(null, null, "CUST_INTER_TF_SERVICE_REQ", new String[]{"TABLE","VIEW"});   
  199.             while(rs.next()){  
  200.                  String tableCat = rs.getString("TABLE_CAT");  //表類別(可為null)   
  201.                  String tableSchemaName = rs.getString("TABLE_SCHEM");//表模式(可能為空),在oracle中獲取的是名稱空間,其它資料庫未知       
  202.                  String tableName = rs.getString("TABLE_NAME");  //表名    
  203.                  String tableType = rs.getString("TABLE_TYPE");  //表型別,典型的型別是 "TABLE"、"VIEW"、"SYSTEM TABLE"、"GLOBAL TEMPORARY"、"LOCAL TEMPORARY"、"ALIAS" 和 "SYNONYM"。  
  204.                  String remarks = rs.getString("REMARKS");       //表備註    
  205.                  System.out.println(tableCat + " - " + tableSchemaName + " - " +tableName + " - " + tableType + " - "   
  206.                         + remarks);    
  207.             }  
  208.         } catch (Exception ex) {  
  209.             ex.printStackTrace();  
  210.         }finally{  
  211.             JdbcUtil.close(rs,conn);  
  212.         }  
  213.     }  
  214.     /** 
  215.      * @Description: 獲取表主鍵資訊 
  216.      * @author: chenzw  
  217.      * @CreateTime: 2014-1-27 下午5:12:53  
  218.      * @throws 
  219.      */  
  220.     public static void getPrimaryKeysInfo() {    
  221.         Connection conn =  getConnection();  
  222.         ResultSet rs = null;  
  223.         try{    
  224.             DatabaseMetaData dbmd = conn.getMetaData();  
  225.             /** 
  226.              * 獲取對給定表的主鍵列的描述 
  227.              * 方法原型:ResultSet getPrimaryKeys(String catalog,String schema,String table); 
  228.              * catalog - 表所在的類別名稱;""表示獲取沒有類別的列,null表示獲取所有類別的列。 
  229.              * schema - 表所在的模式名稱(oracle中對應於Tablespace);""表示獲取沒有模式的列,null標識獲取所有模式的列; 可包含單字元萬用字元("_"),或多字元萬用字元("%"); 
  230.              * table - 表名稱;可包含單字元萬用字元("_"),或多字元萬用字元("%"); 
  231.              */  
  232.             rs = dbmd.getPrimaryKeys(null, null, "CUST_INTER_TF_SERVICE_REQ");    
  233.             while (rs.next()){    
  234.                 String tableCat = rs.getString("TABLE_CAT");  //表類別(可為null)   
  235.                 String tableSchemaName = rs.getString("TABLE_SCHEM");//表模式(可能為空),在oracle中獲取的是名稱空間,其它資料庫未知       
  236.                 String tableName = rs.getString("TABLE_NAME");  //表名    
  237.                 String columnName = rs.getString("COLUMN_NAME");//列名    
  238.                 short keySeq = rs.getShort("KEY_SEQ");//序列號(主鍵內值1表示第一列的主鍵,值2代表主鍵內的第二列)    
  239.                 String pkName = rs.getString("PK_NAME"); //主鍵名稱      
  240.                 System.out.println(tableCat + " - " + tableSchemaName + " - " + tableName + " - " + columnName + " - "  
  241.                        + keySeq + " - " + pkName);       
  242.             }    
  243.         }catch (SQLException e){    
  244.             e.printStackTrace();    
  245.         }finally{  
  246.             JdbcUtil.close(rs,conn);  
  247.         }  
  248.     }    
  249.     /** 
  250.      * @Description: 獲取表索引資訊 
  251.      * @author: chenzw  
  252.      * @CreateTime: 2014-1-27 下午5:12:04  
  253.      * @throws 
  254.      */  
  255.     public static void getIndexInfo() {   
  256.         Connection conn =  getConnection();  
  257.         ResultSet rs = null;  
  258.         try{    
  259.             DatabaseMetaData dbmd = conn.getMetaData();  
  260.             /** 
  261.              * 獲取給定表的索引和統計資訊的描述 
  262.              * 方法原型:ResultSet getIndexInfo(String catalog,String schema,String table,boolean unique,boolean approximate) 
  263.              * catalog - 表所在的類別名稱;""表示獲取沒有類別的列,null表示獲取所有類別的列。 
  264.              * schema - 表所在的模式名稱(oracle中對應於Tablespace);""表示獲取沒有模式的列,null標識獲取所有模式的列; 可包含單字元萬用字元("_"),或多字元萬用字元("%"); 
  265.              * table - 表名稱;可包含單字元萬用字元("_"),或多字元萬用字元("%"); 
  266.              * unique - 該引數為 true時,僅返回唯一值的索引; 該引數為 false時,返回所有索引; 
  267.              * approximate - 該引數為true時,允許結果是接近的資料值或這些資料值以外的值;該引數為 false時,要求結果是精確結果; 
  268.              */  
  269.             rs = dbmd.getIndexInfo(null, null, "CUST_INTER_TF_SERVICE_REQ", false, true);    
  270.             while (rs.next()){    
  271.                 String tableCat = rs.getString("TABLE_CAT");  //表類別(可為null)   
  272.                 String tableSchemaName = rs.getString("TABLE_SCHEM");//表模式(可能為空),在oracle中獲取的是名稱空間,其它資料庫未知       
  273.                 String tableName = rs.getString("TABLE_NAME");  //表名    
  274.                 boolean nonUnique = rs.getBoolean("NON_UNIQUE");// 索引值是否可以不唯一,TYPE為 tableIndexStatistic時索引值為 false;  
  275.                 String indexQualifier = rs.getString("INDEX_QUALIFIER");//索引類別(可能為空),TYPE為 tableIndexStatistic 時索引類別為 null;   
  276.                 String indexName = rs.getString("INDEX_NAME");//索引的名稱 ;TYPE為 tableIndexStatistic 時索引名稱為 null;  
  277.                 /** 
  278.                  * 索引型別:  
  279.                  *  tableIndexStatistic - 此標識與表的索引描述一起返回的表統計資訊  
  280.                  *  tableIndexClustered - 此為叢集索引  
  281.                  *  tableIndexHashed - 此為雜湊索引  
  282.                  *  tableIndexOther - 此為某種其他樣式的索引  
  283.                  */  
  284.                 short type = rs.getShort("TYPE");//索引型別;  
  285.                 short ordinalPosition = rs.getShort("ORDINAL_POSITION");//在索引列順序號;TYPE為 tableIndexStatistic 時該序列號為零;  
  286.                 String columnName = rs.getString("COLUMN_NAME");//列名;TYPE為 tableIndexStatistic時列名稱為 null;  
  287.                 String ascOrDesc = rs.getString("ASC_OR_DESC");//列排序順序:升序還是降序[A:升序; B:降序];如果排序序列不受支援,可能為 null;TYPE為 tableIndexStatistic時排序序列為 null;  
  288.                 int cardinality = rs.getInt("CARDINALITY");   //基數;TYPE為 tableIndexStatistic 時,它是表中的行數;否則,它是索引中唯一值的數量。     
  289.                 int pages = rs.getInt("PAGES"); //TYPE為 tableIndexStatisic時,它是用於表的頁數,否則它是用於當前索引的頁數。  
  290.                 String filterCondition = rs.getString("FILTER_CONDITION"); //過濾器條件,如果有的話(可能為 null)。  
  291.                 System.out.println(tableCat + " - " + tableSchemaName + " - " + tableName + " - " + nonUnique + " - "   
  292.                        + indexQualifier + " - " + indexName + " - " + type + " - " + ordinalPosition + " - " + columnName   
  293.                        + " - " + ascOrDesc + " - " + cardinality + " - " + pages + " - " + filterCondition);       
  294.             }       
  295.         } catch (SQLException e){    
  296.             e.printStackTrace();       
  297.         } finally{  
  298.             JdbcUtil.close(rs,conn);  
  299.         }    
  300.     }    
  301.     /** 
  302.      * @Description: 獲取表中列值資訊 
  303.      * @author: chenzw  
  304.      * @CreateTime: 2014-1-27 下午2:55:56  
  305.      * @throws 
  306.      */  
  307.     public static void getColumnsInfo(){  
  308.         Connection conn =  getConnection();  
  309.         ResultSet rs = null;  
  310.         try{  
  311.             /** 
  312.              * 設定連線屬性,使得可獲取到列的REMARK(備註) 
  313.              */  
  314.             ((OracleConnection)conn).setRemarksReporting(true);   
  315.             DatabaseMetaData dbmd = conn.getMetaData();  
  316.             /** 
  317.              * 獲取可在指定類別中使用的表列的描述。 
  318.              * 方法原型:ResultSet getColumns(String catalog,String schemaPattern,String tableNamePattern,String columnNamePattern) 
  319.              * catalog - 表所在的類別名稱;""表示獲取沒有類別的列,null表示獲取所有類別的列。 
  320.              * schema - 表所在的模式名稱(oracle中對應於Tablespace);""表示獲取沒有模式的列,null標識獲取所有模式的列; 可包含單字元萬用字元("_"),或多字元萬用字元("%"); 
  321.              * tableNamePattern - 表名稱;可包含單字元萬用字元("_"),或多字元萬用字元("%"); 
  322.              * columnNamePattern - 列名稱; ""表示獲取列名為""的列(當然獲取不到);null表示獲取所有的列;可包含單字元萬用字元("_"),或多字元萬用字元("%"); 
  323.              */  
  324.             rs =dbmd.getColumns(null, null, "CUST_INTER_TF_SERVICE_REQ", null);  
  325.             while(rs.next()){  
  326.                 String tableCat = rs.getString("TABLE_CAT");  //表類別(可能為空)                    
  327.                 String tableSchemaName = rs.getString("TABLE_SCHEM");  //表模式(可能為空),在oracle中獲取的是名稱空間,其它資料庫未知       
  328.                 String tableName_ = rs.getString("TABLE_NAME");  //表名    
  329.                 String columnName = rs.getString("COLUMN_NAME");  //列名    
  330.                 int dataType = rs.getInt("DATA_TYPE");     //對應的java.sql.Types的SQL型別(列型別ID)       
  331.                 String dataTypeName = rs.getString("TYPE_NAME");  //java.sql.Types型別名稱(列型別名稱)  
  332.                 int columnSize = rs.getInt("COLUMN_SIZE");  //列大小    
  333.                 int decimalDigits = rs.getInt("DECIMAL_DIGITS");  //小數位數   
  334.                 int numPrecRadix = rs.getInt("NUM_PREC_RADIX");  //基數(通常是10或2) --未知  
  335.                 /** 
  336.                  *  0 (columnNoNulls) - 該列不允許為空 
  337.                  *  1 (columnNullable) - 該列允許為空 
  338.                  *  2 (columnNullableUnknown) - 不確定該列是否為空 
  339.                  */  
  340.                 int nullAble = rs.getInt("NULLABLE");  //是否允許為null    
  341.                 String remarks = rs.getString("REMARKS");  //列描述    
  342.                 String columnDef = rs.getString("COLUMN_DEF");  //預設值    
  343.                 int charOctetLength = rs.getInt("CHAR_OCTET_LENGTH");    // 對於 char 型別,該長度是列中的最大位元組數   
  344.                 int ordinalPosition = rs.getInt("ORDINAL_POSITION");   //表中列的索引(從1開始)    
  345.                 /**  
  346.                  * ISO規則用來確定某一列的是否可為空(等同於NULLABLE的值:[ 0:'YES'; 1:'NO'; 2:''; ]) 
  347.                  * YES -- 該列可以有空值;  
  348.                  * NO -- 該列不能為空; 
  349.                  * 空字串--- 不知道該列是否可為空 
  350.                  */    
  351.                 String isNullAble = rs.getString("IS_NULLABLE");    
  352.                 /**  
  353.                  * 指示此列是否是自動遞增  
  354.                  * YES -- 該列是自動遞增的 
  355.                  * NO -- 該列不是自動遞增 
  356.                  * 空字串--- 不能確定該列是否自動遞增 
  357.                  */    
  358.                 //String isAutoincrement = rs.getString("IS_AUTOINCREMENT");   //該引數測試報錯      
  359.                 System.out.println(tableCat + " - " + tableSchemaName + " - " + tableName_ + " - " + columnName +   
  360.                         " - " + dataType + " - " + dataTypeName + " - " + columnSize + " - " + decimalDigits + " - "   
  361.                         + numPrecRadix + " - " + nullAble + " - " + remarks + " - " + columnDef + " - " + charOctetLength  
  362.                         + " - " + ordinalPosition + " - " + isNullAble );   
  363.             }  
  364.         }catch(SQLException ex){  
  365.             ex.printStackTrace();  
  366.         }finally{  
  367.             JdbcUtil.close(rs,conn);  
  368.         }  
  369.     }  
  370.     /** 
  371.      * @Description: TODO 
  372.      * @author: chenzw  
  373.      * @CreateTime: 2014-1-17 下午2:47:45 
  374.      * @param args  
  375.      * @throws  
  376.      */  
  377.     public static void main(String[] args) {  
  378.         getDataBaseInfo();  //獲取資料庫資訊  
  379.         getSchemasInfo(); //獲取資料庫所有Schema  
  380.         getTablesList();  //獲取某使用者下所有的表  
  381.         getTablesInfo();  //獲取表資訊  
  382.         getPrimaryKeysInfo(); //獲取表主鍵資訊  
  383.         getIndexInfo();  //獲取表索引資訊  
  384.         getColumnsInfo(); //獲取表中列值資訊  
  385.     }  
  386. }