2010-05-25 16 views
5

¿Alguien sabe si hay una biblioteca java para analizar un esquema MySQL? En el código, quiero poder determinar las tablas y los campos especificados en un esquema. ¿O tendré que escribir el mío?¿Un analizador de esquema MySQL en Java?

Gracias Richard.

Editar: simplemente quiere evitar reinventar la rueda innecesariamente :)

+0

Dependiendo de lo que se necesita porque no puede haber una manera de hacerlo en forma bastante sencilla. Entonces, ¿cuál será la aplicación de esto? De lo contrario tienen un vistazo a http://stackoverflow.com/questions/660609/sql-parser-library-for-java – bobah

+0

@bobah - Sí bien http://stackoverflow.com/questions/660609/sql-parser- library-for-java tiene la respuesta: jsqlparser. gracias –

Respuesta

2

responder a mi propia pregunta:

Am usando jsqlparser http://jsqlparser.sourceforge.net/

Este analiza las declaraciones individuales, no por múltiples declaraciones tales como que se encuentran en un esquema. Así que divide el esquema en ';'. Tampoco le gusta el carácter '' ', por lo que deben eliminarse. Código para obtener los nombres de columna de una tabla en particular:

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); 
    } 

} 

} 
1

Por qué no utilizar DatabaseMetaData para averiguar las tablas y columnas? Esto supone que el esquema expresado en SQL se ejecutó contra la base de datos a la que está conectado, pero no es una suposición difícil de satisfacer.

MySQL podría simplemente importar los datos si tiene los datos en formato CSV. Profundizaría en las herramientas de MySQL antes de escribir código Java para hacer tal cosa. Si eso no funciona, encontraría una herramienta de ETL para ayudarme. Escribir Java sería mi solución de último recurso.

+0

desafortunadamente este código se está ejecutando (actualmente) antes de que se construya la base de datos. Sin embargo, podría cambiar el orden de las cosas, así que gracias por la sugerencia –

+1

A menos que su código Java tenga que crear la base de datos (y no debería), no creo que deba analizar SQL DDL. – duffymo

+0

no, no está creando el db. lo que está haciendo es crear un archivo para importar db con las columnas definidas en el esquema, los valores tomados de un archivo de datos de origen que contiene estas columnas más un montón de otros en un orden no estático. –

0

Es posible que desee considerar el uso de código de Alibaba del Druid project. Aunque está diseñado como una biblioteca de agrupación de conexiones sofisticada, este proyecto admite un parser and AST muy avanzado para ANSI SQL y dialectos no ANSI como MySQL, Oracle, SQL Server, etc. El proyecto es de código abierto y lleva la versión muy liberal de Apache License versión 2.0.

La entrada principal a esta parte de la biblioteca es SQLUtils.java. Puede utilizar los valores devueltos de SQLUtils.parseStatements acceder a un modelo mecanografiada de los estados:

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() 
    } 
} 
Cuestiones relacionadas