One of the problems of Java is not having support for multiline strings. It will be added in JDK12 JEP 326: Raw String Literals, but I'll probably be stuck with Java 8 for a long time. And I doubt that I'm the only one... Annoying thing about single line strings is handling large sql statements, so you have to write something like:

String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" +
               "WHERE `CITY` = ‘INDIANAPOLIS'\n" +
               "ORDER BY `EMP_ID`, `LAST_NAME`;\n";

There can be a lot more complicated sql queries, and a lot more sql queries, which makes the code and queries hard to follow and unreadable.

My hack is externalizing queries to a yaml file with the help of Jackson.

Dependencies

We'll use Jackson for deserializing Yaml file. Check latest versions at mvnrepository.

<dependencies>
    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-yaml</artifactId>
        <version>2.8.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.0</version>
    </dependency>
</dependencies>

Code

Step 1 - create your yaml file

Below is a simple sql query, written in yaml file. In actual usage, queries might be much more complex than this example. sql.yaml

select1: >
  SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
  WHERE `CITY` = ‘INDIANAPOLIS'
  ORDER BY `EMP_ID`, `LAST_NAME`;

Step 2 - create yaml loader

Create an abstract class, so we could use it to load more yaml files if needed. YamlDocument.java

package yaml;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
public abstract class YamlDocument {
public static&lt;T&gt; T load(Class&lt;T&gt; clazz, String resource){
    return YamlDocument.load(clazz, clazz.getResource(resource));
}

public static&lt;T&gt; T load(Class&lt;T&gt; clazz, java.net.URL resource){
    ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
    try {
        return mapper.readValue(resource, clazz);
    } catch (Exception e) {
        throw new RuntimeException(
        String.format("Could not getInstance SqlResource from %s", resource), e);
    }
}

Step 3 - implement loader

We'll implement yaml loader in the SqlResource singleton - resource needs to be loaded only once.

SqlResource.java

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

public class SqlResource {
    public String select1;

    private static volatile SqlResource instance;
    public static SqlResource getInstance() {
        SqlResource result = instance;
        if (result == null) {
            synchronized (SqlResource.class) {
                result = instance;
                if (result == null) {
                    instance = result = YamlDocument.load(
                    SqlResource.class, "sql.yaml");
                }
            }
        }
        return result;
    }
}

Use in code like SqlResource.getInstance().select1.