JDBC如何判斷資料庫的表是否存在
實現原理:主要是利用DatabaseMetaData.getTables(...)這個方法實現的,但是每一種資料庫還存在一些差異,具體見下面詳解。
一、getTables(...)方法說明
Java程式碼- ResultSet DatabaseMetaData.getTables(String catalog,
- String schemaPattern,
- String tableNamePattern,
-
String types[]) throws
- catalog - 資料庫目錄名稱,可設為null,(具體JDBC驅動的實現不一樣在MySQL中指資料庫名)。
- schemaPattern - 方案名稱的樣式,可設為null,( 具體JDBC驅動的實現不一樣, 在Oracle中指使用者名稱)。
- tableNamePattern - 表名稱的樣式,可以包含匹配符比如:"TEST%"
- types - 要包括的表型別組成的列表,可設為null,表示所有的。
- types的常量值為:
- "TABLE"
- "VIEW"
- "SYSTEM TABLE"
- "GLOBAL TEMPORARY"
- "LOCAL TEMPORARY"
- "ALIAS", "SYNONYM"
各種資料庫系統對Catalog和Schema的支援和實現方式是不一樣的,針對具體問題需要參考具體的產品說明書,比較簡單而常用的實現方式是使用資料庫名作為Catalog名,使用使用者名稱作為Schema名,具體可參見下表:
常用資料庫Catalog和Schema對照表
供應商 |
Catalog支援 |
Schema支援 |
Oracle |
不支援 |
Oracle User ID |
MySQL |
不支援 |
資料庫名 |
MS SQL Server |
資料庫名 |
物件屬主名,2005版開始有變 |
DB2 |
指定資料庫物件時,Catalog部分省略 |
Catalog屬主名 |
Sybase |
資料庫名 |
資料庫屬主名 |
Informix |
不支援 |
不需要 |
PointBase |
不支援 |
資料庫名 |
二、常用資料庫舉例
1. MySQL示例
url = jdbc:mysql://localhost:3306/michaeldemo
user = "root";
getTables("michaeldemo", null, tableName,new String[] { "TABLE" });
看到這有人會問,你上面的對照表中不是說過MySQL不支援Catalog,而是支援Schema,這裡怎麼又設定第一個引數呢?不是互相矛盾麼?的確是有這個疑問,不過當你看過MySQL的JDBC驅動原始碼後你就會明白其中原因了,我摘錄一部分實現程式碼具體如下:
Java程式碼- String sql = "SELECT TABLE_SCHEMA AS TABLE_CAT, "
- + "NULL AS TABLE_SCHEM, TABLE_NAME, "
- + "CASE WHEN TABLE_TYPE='BASE TABLE' THEN 'TABLE' WHEN TABLE_TYPE='TEMPORARY' THEN 'LOCAL_TEMPORARY' ELSE TABLE_TYPE END AS TABLE_TYPE, "
- + "TABLE_COMMENT AS REMARKS "
- + "FROM INFORMATION_SCHEMA.TABLES WHERE "
- + "TABLE_SCHEMA LIKE ? AND TABLE_NAME LIKE ? AND TABLE_TYPE IN (?,?,?) "
- + "ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME";
可知引數catalog在MySQL中實際是當做Schema來用的,所以這就解釋了為什麼mysql中設定的卻是 引數catalog的值。
2. Oracle示例
url = jdbc:oracle:thin:@localhost:1521:ORA11g
user = "demo";
getTables(null, "DEMO", tableName,new String[] { "TABLE" });
二、測試程式碼
JdbcCheckTableExitDemo.java
Java程式碼- package michael.jdbc;
- import java.sql.Connection;
- import java.sql.DatabaseMetaData;
- import java.sql.DriverManager;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- /**
- * @blog http://sjsky.iteye.com
- * @author Michael
- */
- public class JdbcCheckTableExitDemo {
- private static String url = "jdbc:mysql://localhost:3306/michaeldemo";
- private static String user = "root";
- private static String password = "";
- private static String driver = "com.mysql.jdbc.Driver";
- // private static String url = "jdbc:oracle:thin:@localhost:1521:ORA11g";
- // private static String user = "demo";
- // private static String password = "111111";
- // private static String driver = "oracle.jdbc.driver.OracleDriver";
- /**
- * @param args
- */
- public static void main(String[] args) {
- Connection conn = null;
- String tableName = "TB_MYTEST";
- try {
- Class.forName(driver);
- conn = DriverManager.getConnection(url, user, password);
- conn.setAutoCommit(false);
- DatabaseMetaData meta = conn.getMetaData();
- // 第一個引數catalog在MySQL中對應資料庫名:michaeldemo
- ResultSet rsTables = meta.getTables("michaeldemo", null, tableName,
- new String[] { "TABLE" });
- // 第二個引數schemaPattern在ORACLE中對應使用者名稱:demo
- // ResultSet rsTables = meta.getTables(null, "DEMO", tableName,
- // new String[] { "TABLE" });
- System.out.println("getTables查詢資訊如下:");
- System.out
- .println("TABLE_CAT \t TABLE_SCHEM \t TABLE_NAME \t TABLE_TYPE");
- while (rsTables.next()) {
- System.out.println(rsTables.getString("TABLE_CAT") + "\t"
- + rsTables.getString("TABLE_SCHEM") + "\t"
- + rsTables.getString("TABLE_NAME") + "\t"
- + rsTables.getString("TABLE_TYPE"));
- }
- rsTables.close();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (null != conn) {
- conn.close();
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
Oracle中執行結果:
getTables查詢資訊如下:TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE
null DEMO TB_MYTEST TABLE
MySQL中執行結果:
getTables查詢資訊如下:TABLE_CAT TABLE_SCHEM TABLE_NAME TABLE_TYPE
michaeldemo null TB_MYTEST TABLE