用Java解析SQL文件并获取语句和注释

用Java解析SQL文件并获取语句和注释,java,sql,parsing,comments,Java,Sql,Parsing,Comments,可能重复: 我想使用ready解决方案来解析SQL文件。文件可以包含注释、SQL语句、DDL。 我需要得到评论,所有的SQL语句。 有人知道现成的解决方案吗?我不想再有一个方轮了 附言。 请注意,我不需要忽略注释,我需要从文件中的注释中获取文本,我建议您看看iBatis,它使带有JDBC的手写DAO和DTO完全过时 在iBatis之前,我使用将SQL保存在单独的SQL文件中,并在需要时检索正确的SQL。我不再使用它了。。。因为在实际的Java代码中,这只比SQL稍微好一点 SQL文件的语法如下

可能重复:

我想使用ready解决方案来解析SQL文件。文件可以包含注释、SQL语句、DDL。 我需要得到评论,所有的SQL语句。 有人知道现成的解决方案吗?我不想再有一个方轮了

附言。
请注意,我不需要忽略注释,我需要从文件中的注释中获取文本,我建议您看看iBatis,它使带有JDBC的手写DAO和DTO完全过时

在iBatis之前,我使用将SQL保存在单独的SQL文件中,并在需要时检索正确的SQL。我不再使用它了。。。因为在实际的Java代码中,这只比SQL稍微好一点

SQL文件的语法如下所示:

-- I added comments like this...
[id] {
  any SQL statement... (quite frankly any text).
} 

[id2] {
  ...
}

...
然后,使用以下简单的解析器类:

public class SQLParser {
    private static Logger logger = LoggerUtility.getLogger(SQLParser.class);

    private String raw;
    private Map<String, String> sql;

    public SQLParser(InputStream is) {
        sql = new HashMap<String, String>();
        try {
            read(is);
            parse();
        } catch (IOException e) {
            logger.debug(LoggerCodes.TRACE, "Input Stream could not be successfull read!");
        }
    }

    private void read(InputStream is) throws IOException {
        StringBuilder builder = new StringBuilder();
        BufferedReader in = new BufferedReader(new InputStreamReader(is));
        String line = in.readLine();
        while (line != null) {
            builder.append(line + "\n");
            line = in.readLine();
        }
        raw = builder.toString();
    }

    public String getSql(String sqlId) {
        return sql.get(sqlId);
    }

    public PreparedStatement getSql(Connection connection, String sqlId) throws SQLException {
        String statement = sql.get(sqlId);
        return connection.prepareStatement(statement);
    }

    private void parse() {
        if (raw == null) {
            logger.debug(LoggerCodes.TRACE, "No String to parse for SQL statements!");
            return;
        }

        String regex = "\\.*\\[(\\S*)\\]\\s*\\{\\s*([^\\}]*)\\s*\\}";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(raw);
        while (m.find()) {
            String key = m.group(1);
            String body = m.group(2);
            logger.debug("Adding " + key + " to SQL map.");
            sql.put(key, body.trim());
        }
    }
}
公共类SQLParser{
私有静态记录器Logger=LoggerUtility.getLogger(SQLParser.class);
私有字符串原始;
私有映射sql;
公共SQLParser(InputStream为){
sql=新的HashMap();
试一试{
阅读(is);
parse();
}捕获(IOE异常){
debug(LoggerCodes.TRACE,“无法成功读取输入流!”);
}
}
私有无效读取(InputStream is)引发IOException{
StringBuilder=新的StringBuilder();
BufferedReader in=新的BufferedReader(新的InputStreamReader(is));
String line=in.readLine();
while(行!=null){
builder.append(第+行“\n”);
line=in.readLine();
}
raw=builder.toString();
}
公共字符串getSql(字符串sqlId){
返回sql.get(sqlId);
}
公共PreparedStatement getSql(连接,字符串sqlId)引发SQLException{
String语句=sql.get(sqlId);
返回连接。准备声明(声明);
}
私有void parse(){
如果(原始==null){
debug(LoggerCodes.TRACE,“没有要解析的SQL语句字符串!”);
返回;
}
String regex=“\\.\\\[(\\S*)\\]\\S*\\{\\S*([^\\}]*)\\S*\}”;
Pattern p=Pattern.compile(regex);
匹配器m=p.匹配器(原始);
while(m.find()){
字符串键=m.group(1);
串体=m组(2);
debug(“向SQL映射添加“+key+”);
sql.put(key,body.trim());
}
}
}

然后简单地创建一个以上的新实例,并调用sqlParser.getSql(id)以获得正确的SQL。

已经有人问过我想满足您的好奇心。我帮你找过了。zql、jsqlparser不提供访问注释的机会,通用SQL解析器不是免费的。ANTLR是一个解决问题的工具,但不是问题的解决方案。如果你能为你的问题找到现成的解决方案,我会感到惊讶(评论和所有)。我认为你很可能会找到一个工具(比如ANTLR),使工作相对容易。。。此解决方案将忽略注释,但我相信您可以相应地进行调整。我想描述一下我的任务:我确实有具有不同sql脚本的现有文件:DDL create table/views语句、selects、e.t.c。我想在这些文件中添加宏。宏将在注释中。所以sql文件将保持有效,我的工具可以读取它们,从注释中提取宏并执行其他操作。这样做的目的不是破坏存储在文件中的现有SQL代码,而是添加更多功能。谢谢Jaco,我在java项目中对sql问题使用了相同的方法。我讨厌将SQL代码内联到Java代码中。真难看(