代码之家  ›  专栏  ›  技术社区  ›  Richard H

Java中的MySQL模式解析器?

  •  5
  • Richard H  · 技术社区  · 16 年前

    有没有人知道是否有一个Java库来解析MySQL模式?在代码中,我希望能够确定模式中指定的表和字段。还是我需要自己写?

    谢谢李察。

    编辑: 只是想避免不必要地重新发明轮子:)

    3 回复  |  直到 9 年前
        1
  •  3
  •   Richard H    16 年前

    回答我自己的问题:

    AM使用JSQLParser http://jsqlparser.sourceforge.net/

    这将解析单个语句,而不是模式中的多个语句。所以在“;”上拆分架构。它也不喜欢“`”字符,所以需要去掉这些字符。获取特定表的列名的代码:

    public class BUDataColumnsFinder {
    
    public static String[] readSql(String schema) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(schema)));
        String mysql = "";
        String line;
        while ((line = br.readLine()) != null) {
            mysql = mysql + line;
        }
        br.close();
        mysql = mysql.replaceAll("`", "");
        return mysql.split(";");
    }
    
    public static List<String> getColumnNames(String tableName, String schemaFile) throws JSQLParserException, IOException {
    
        CCJSqlParserManager pm = new CCJSqlParserManager();
        List<String> columnNames = new ArrayList<String>();
    
        String[] sqlStatements = readSql(schemaFile);
    
        for (String sqlStatement : sqlStatements) {
    
            Statement statement = pm.parse(new StringReader(sqlStatement));
    
            if (statement instanceof CreateTable) {
    
                CreateTable create = (CreateTable) statement;
                String name = create.getTable().getName();
    
                if (name.equalsIgnoreCase(tableName)) {
                    List<ColumnDefinition> columns = create.getColumnDefinitions();
                    for (ColumnDefinition def : columns) {
                        columnNames.add(def.getColumnName());
                    }
                    break;
                }
            }
        }
    
        return columnNames;
    }
    
    
    public static void main(String[] args) throws Exception {
    
        String schemaFile = "/home/john/config/bu-schema.sql";
    
        String tableName = "records";
    
        List<String> columnNames = BUDataColumnsFinder.getColumnNames(tableName, schemaFile);
    
        for (String name : columnNames) {
            System.out.println("name: " + name);
        }
    
    }
    
    }
    
        2
  •  1
  •   duffymo    16 年前

    为什么不使用databasemetadata来查找表和列呢?这假定以SQL表示的模式是针对您所连接的数据库运行的,但这不是一个很难满足的假设。

    如果您有csv格式的数据,MySQL可能只需导入数据。在编写Java代码之前,我会深入研究MySQL工具。如果这不起作用,我会找到一个ETL工具来帮助我。编写Java将是我最后的解决方案。

        3
  •  1
  •   btiernay    9 年前

    你可以考虑使用阿里巴巴的代码 Druid project . 虽然设计为复杂的连接池库,但此项目支持非常高级的 parser and AST 对于ansi-sql和非ansi语言,如mysql、oracle、sql-server等,该项目是开放源代码的,具有非常宽松的Apache许可证版本2.0。

    进入图书馆这一部分的主要入口是 SQLUtils.java . 可以使用从返回的值 SQLUtils.parseStatements 要访问语句的类型化模型:

    List<SQLStatement> statements = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
    for (SQLStatement statement : statements) {
       if (statement instanceof MySqlCreateTableStatment) {
          MySqlCreateTableStatment createTable = (MySqlCreateTableStatment) statement;
          // Use methods like: createTable.getTableSource()
       }
    }