通常,在应用程序中放置SQL查询的位置?

jai*_*jai 8 java sql

在应用程序中放置SQL查询的最佳位置是什么?

查询可能很大,需要格式化.

使用StringBuilder附加查询看起来非常混乱.

将它们存储在文件中并在每次发出请求时读取它们 - 看起来都是个坏主意.(但我认为从文件读取可以放在静态块中)

Sea*_*oyd 16

将SQL查询保存在您在类加载时读取的常量资源文件中:

private static final String PERSON_QUERY;

static{
    InputStream str = null;
    try{
        str = ThisClass.class.getResourceAsStream("/path/to/query.sql");
        PERSON_QUERY = IOUtils.toString(str);
    }catch(IOException e){
        throw new IllegalStateException("Failed to read SQL query", e);
    }finally{
        IOUtils.closeQuitely(str);
    }

}
Run Code Online (Sandbox Code Playgroud)

这样您就可以使用自己喜欢的编辑器来编辑SQL,但仍然可以在java中以常量形式获取查询.

如果你这么做,请将代码解压缩到辅助方法:

public static String loadResourceToString(final String path){
    final InputStream stream =
        Thread
            .currentThread()
            .getContextClassLoader()
            .getResourceAsStream(path);
    try{
        return IOUtils.toString(stream);
    } catch(final IOException e){
        throw new IllegalStateException(e);
    } finally{
        IOUtils.closeQuietly(stream);
    }
}
Run Code Online (Sandbox Code Playgroud)

并在静态块中使用它:

private static final String PERSON_QUERY;
private static final String ADDRESS_QUERY;
private static final String AGE_QUERY;

static{
    PERSON_QUERY = Helper.loadResourceToString("queries/personQuery.sql");
    ADDRESS_QUERY = Helper.loadResourceToString("queries/addressQuery.sql");
    AGE_QUERY = Helper.loadResourceToString("queries/ageQuery.sql");
}
Run Code Online (Sandbox Code Playgroud)

在我看来,不同的语言应该总是分开的.从Java代码组装SQL,HTML,XML,JavaScript等是一种可怕的做法.尽可能使用像Velocity这样的普通模板或模板引擎.这给了你很多好处,其中之一就是你可以在不重新编译java类的情况下更改模板.

PS:我在上面的代码中使用了Apache Commons/IO,但它没有必要,只是更容易.