【问题标题】:How to get all table names from a database?如何从数据库中获取所有表名?
【发布时间】:2011-02-16 08:10:56
【问题描述】:

我想从数据库模式中检索所有表名,并且如果可能的话,获取所有以指定前缀开头的表。

我尝试使用 JDBC 的 connection.getMetaData().getTables(),但它根本不起作用。

Connection jdbcConnection = DriverManager.getConnection("", "", "");
DatabaseMetaData m = jdbcConnection.getMetaData();
ResultSet tables = m.getTables(jdbcConnection.getCatalog(), null, "TAB_%", null);
for (int i = 0; i < tables.getMetaData().getColumnCount(); i++) {
   System.out.println("table = " + tables.getMetaData().getTableName(i));
}

有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: java database jdbc database-metadata


    【解决方案1】:

    您需要遍历调用 next() 的 ResultSet。

    这是来自java2s.com的示例:

    DatabaseMetaData md = conn.getMetaData();
    ResultSet rs = md.getTables(null, null, "%", null);
    while (rs.next()) {
      System.out.println(rs.getString(3));
    }
    

    3 列是TABLE_NAME(参见DatabaseMetaData::getTables 的文档)。

    【讨论】:

    • 如果这对您来说失败了(就像我一样),您需要确保数据库用户实际上可以在数据库中显示表。
    • 显示所有数据库中的所有表。您可以将数据库名称作为第一个参数传递,以仅显示该数据库中的表。
    • 对于 mysql,ResultSet rs = md.getTables(connection.getCatalog(), null, "%", new String [] {"TABLE"});只为您提供当前架构的表。
    • 我们为什么要在这里给出 %?我们不应该使用“.*”之类的东西吗?
    • @Pardhu:这不是正则表达式,% 在 SQL 中用作通配符。
    【解决方案2】:
     public void getDatabaseMetaData()
        {
            try {
    
                DatabaseMetaData dbmd = conn.getMetaData();
                String[] types = {"TABLE"};
                ResultSet rs = dbmd.getTables(null, null, "%", types);
                while (rs.next()) {
                    System.out.println(rs.getString("TABLE_NAME"));
                }
            } 
                catch (SQLException e) {
                e.printStackTrace();
            }
        }
    

    【讨论】:

    • 显示所有数据库中的所有表。您可以将数据库名称作为第一个参数传递,以仅显示该数据库中的表。
    • 从驱动mysql-connector-java 8.0.22开始metaData.getTables从所有数据库返回所有用户可见的表,忽略参数'schema'
    【解决方案3】:

    在您的示例中,问题是在 DatabaseMetaData 的 getTables 函数中传递表名模式。

    有些数据库支持大写标识符,有些支持小写标识符。例如 oracle 以大写形式获取表名,而 postgreSQL 以小写形式获取表名。

    DatabaseMetaDeta 提供了判断数据库如何存储标识符的方法,可以混合大小写,大写,小写见:http://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#storesMixedCaseIdentifiers()

    从下面的示例中,您可以获得所有表格和提供表格名称模式的视图,如果您只想要表格然后从 TYPES 数组中删除“VIEW”。

    public class DBUtility {
        private static final String[] TYPES = {"TABLE", "VIEW"};
        public static void getTableMetadata(Connection jdbcConnection, String tableNamePattern, String schema, String catalog, boolean isQuoted) throws HibernateException {
                try {
                    DatabaseMetaData meta = jdbcConnection.getMetaData();
                    ResultSet rs = null;
                    try {
                        if ( (isQuoted && meta.storesMixedCaseQuotedIdentifiers())) {
                            rs = meta.getTables(catalog, schema, tableNamePattern, TYPES);
                        } else if ( (isQuoted && meta.storesUpperCaseQuotedIdentifiers())
                            || (!isQuoted && meta.storesUpperCaseIdentifiers() )) {
                            rs = meta.getTables(
                                    StringHelper.toUpperCase(catalog),
                                    StringHelper.toUpperCase(schema),
                                    StringHelper.toUpperCase(tableNamePattern),
                                    TYPES
                                );
                        }
                        else if ( (isQuoted && meta.storesLowerCaseQuotedIdentifiers())
                                || (!isQuoted && meta.storesLowerCaseIdentifiers() )) {
                            rs = meta.getTables( 
                                    StringHelper.toLowerCase( catalog ),
                                    StringHelper.toLowerCase(schema), 
                                    StringHelper.toLowerCase(tableNamePattern), 
                                    TYPES 
                                );
                        }
                        else {
                            rs = meta.getTables(catalog, schema, tableNamePattern, TYPES);
                        }
    
                        while ( rs.next() ) {
                            String tableName = rs.getString("TABLE_NAME");
                            System.out.println("table = " + tableName);
                        }
    
    
    
                    }
                    finally {
                        if (rs!=null) rs.close();
                    }
                }
                catch (SQLException sqlException) {
                    // TODO 
                    sqlException.printStackTrace();
                }
    
        }
    
        public static void main(String[] args) {
            Connection jdbcConnection;
            try {
                jdbcConnection = DriverManager.getConnection("", "", "");
                getTableMetadata(jdbcConnection, "tbl%", null, null, false);
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      如果您想使用高级 API,它隐藏了数据库架构元数据周围的大量 JDBC 复杂性,请查看这篇文章:http://www.devx.com/Java/Article/32443/1954

      【讨论】:

        【解决方案5】:
        public static ArrayList<String> getTablesList(Connection conn)
                    throws SQLException {
        
                ArrayList<String> listofTable = new ArrayList<String>();
        
                DatabaseMetaData md = conn.getMetaData();
        
                ResultSet rs = md.getTables(null, null, "%", null);
        
                while (rs.next()) {
                    if (rs.getString(4).equalsIgnoreCase("TABLE")) {
                        listofTable.add(rs.getString(3));
                    }
                }
                return listofTable;
            }
        

        【讨论】:

          【解决方案6】:

          在较新版本的 MySQL 连接器中,如果未通过目录,也会列出默认表

                  DatabaseMetaData dbMeta = con.getMetaData();
                  //con.getCatalog() returns database name
                  ResultSet rs = dbMeta.getTables(con.getCatalog(), "", null, new String[]{"TABLE"});
                  ArrayList<String> tables = new ArrayList<String>();
                  while(rs.next()){
                      String tableName = rs.getString("TABLE_NAME");
                      tables.add(tableName);
                  }
                  return tables;
          

          【讨论】:

            【解决方案7】:
            DatabaseMetaData md = conn.getMetaData();
            String[] types = {"TABLE"};
            ResultSet rs = md.getTables("Your_DB_Name", null, "%", types);
            while (rs.next()) {
                System.out.println(rs.getString("TABLE_NAME"));
            }
            

            【讨论】:

              【解决方案8】:
              @Transactional
              @RequestMapping(value = { "/getDatabaseTables" }, method = RequestMethod.GET)
              public @ResponseBody String getDatabaseTables() throws Exception{ 
              
                  Connection con = ((SessionImpl) sessionFactory.getCurrentSession()).connection();
                  DatabaseMetaData md = con.getMetaData();
                  ResultSet rs = md.getTables(null, null, "%", null);
                  HashMap<String,List<String>> databaseTables = new HashMap<String,List<String>>();
                  List<String> tables = new ArrayList<String>();
                  String db = "";
                  while (rs.next()) {
                      tables.add(rs.getString(3));
                      db = rs.getString(1);
                  }
                  List<String> database = new ArrayList<String>();
                  database.add(db);
                  databaseTables.put("database", database);
                  Collections.reverse(tables);
                  databaseTables.put("tables", tables);
                  return new ObjectMapper().writeValueAsString(databaseTables);
              }
              
              @Transactional
              @RequestMapping(value = { "/getTableDetails" }, method = RequestMethod.GET)
              public @ResponseBody String getTableDetails(@RequestParam(value="tablename")String tablename) throws Exception{ 
                  System.out.println("...tablename......"+tablename);
                  Connection con = ((SessionImpl) sessionFactory.getCurrentSession()).connection();       
                   Statement st = con.createStatement();
                   String sql = "select * from "+tablename;
                   ResultSet rs = st.executeQuery(sql);
                   ResultSetMetaData metaData = rs.getMetaData();
                   int rowCount = metaData.getColumnCount();    
                   List<HashMap<String,String>> databaseColumns = new ArrayList<HashMap<String,String>>();
                   HashMap<String,String> columnDetails = new HashMap<String,String>();
                   for (int i = 0; i < rowCount; i++) {
                       columnDetails = new HashMap<String,String>();
                       Method method = com.mysql.jdbc.ResultSetMetaData.class.getDeclaredMethod("getField", int.class);
                       method.setAccessible(true);
                       com.mysql.jdbc.Field field = (com.mysql.jdbc.Field) method.invoke(metaData, i+1);
                       columnDetails.put("columnName", field.getName());//metaData.getColumnName(i + 1));
                       columnDetails.put("columnType", metaData.getColumnTypeName(i + 1));
                       columnDetails.put("columnSize", field.getLength()+"");//metaData.getColumnDisplaySize(i + 1)+"");
                       columnDetails.put("columnColl", field.getCollation());
                       columnDetails.put("columnNull", ((metaData.isNullable(i + 1)==0)?"NO":"YES"));
                       if (field.isPrimaryKey()) {
                           columnDetails.put("columnKEY", "PRI");
                       } else if(field.isMultipleKey()) {
                           columnDetails.put("columnKEY", "MUL");
                       } else if(field.isUniqueKey()) {
                           columnDetails.put("columnKEY", "UNI");
                       } else {
                           columnDetails.put("columnKEY", "");
                       }
                       columnDetails.put("columnAINC", (field.isAutoIncrement()?"AUTO_INC":""));
                       databaseColumns.add(columnDetails);
                   }
                  HashMap<String,List<HashMap<String,String>>> tableColumns = new HashMap<String,List<HashMap<String,String>>>();
                  Collections.reverse(databaseColumns);
                  tableColumns.put("columns", databaseColumns);
                  return new ObjectMapper().writeValueAsString(tableColumns);
              }
              

              【讨论】:

                猜你喜欢
                • 2016-08-14
                • 1970-01-01
                • 2011-09-07
                • 2011-11-17
                • 2013-03-01
                • 2011-04-30
                • 2011-02-17
                • 2015-04-05
                • 2016-05-13
                相关资源
                最近更新 更多