Queryless Maven Plugin

Plugin generates java constants classes from externalized query files.

License

License

Categories

Categories

Maven Build Tools
GroupId

GroupId

com.github.paveljakov
ArtifactId

ArtifactId

queryless-plugin-maven
Last Version

Last Version

1.0.2
Release Date

Release Date

Type

Type

maven-plugin
Description

Description

Queryless Maven Plugin
Plugin generates java constants classes from externalized query files.
Project URL

Project URL

https://github.com/paveljakov/queryless
Source Code Management

Source Code Management

https://github.com/paveljakov/queryless

Download queryless-plugin-maven

How to add to project

<plugin>
    <groupId>com.github.paveljakov</groupId>
    <artifactId>queryless-plugin-maven</artifactId>
    <version>1.0.2</version>
</plugin>

Dependencies

compile (3)

Group / Artifact Type Version
org.apache.maven : maven-plugin-api jar 3.0
org.apache.maven : maven-project jar 2.2.1
com.github.paveljakov : queryless-core jar 1.0.2

provided (2)

Group / Artifact Type Version
org.apache.maven.plugin-tools : maven-plugin-annotations jar 3.4
org.projectlombok : lombok jar 1.18.4

test (3)

Group / Artifact Type Version
junit : junit jar 4.12
org.mockito : mockito-core jar 2.23.0
org.assertj : assertj-core jar 3.11.1

Project Modules

There are no modules declared in this project.

Queryless

Queryless is a Maven and Gradle plugin that generates Java classes from resource files containing externalized SQL or other type queries.

Summary

Aim of this simple project is to answer question that sometimes arises when using string based queries in Java source code - where to put query text?

Usually there are three main options:

  • Write queries text directly in Java code as a constant or directly as string literal.
    • Main advantage is that query text can be quickly located and in case of inline string literal - quickly modified.
    • Main disadvantage of this option is query readability and maintainability, since Java does not support multiline strings.
  • Externalize queries into properties or other configuration files.
    • Main advantage is that queries and Java code is not mixed also multiline queries can be much more readable.
    • Main disadvantage is that queries text is not easily located and can not be quickly viewed from Java code.
  • Use frameworks such as JOOQ.
    • Advantages and disadvantages of this option is kind of obvious, but in general there might be times when we can not or don't want to use other frameworks.

Queryless aims to solve this issue by mixing two of the three options mentioned above, keep queries external from Java code and generate classes with query constants and useful javadocs. This solution provides following advantages:

  • Java code and query text is separate.
  • Queries can be written in native files (such as *.sql) and take advantage of IDE or other tools support.
  • Generated classes and constants has javadocs with original query text, so query can be easily viewed from Java code.
  • Java code for query constants are automatically generated by Maven or Gradle plugin.
  • Plugin supports collecting multiple source files into bundles (query constant classes) and also supports nested bundles to enrich readability and structure.

Example

Lets say we have SQL file queries.sql located at /src/main/resources/queries/:

-- id: employee-find
-- Finds employees by ID
SELECT
    ID,
    NAME,
    AGE,
    DEPARTMENT
FROM
    EMPLOYEE
WHERE
    ID = :id

Using simple Maven plugin configuration:

<plugin>
    <groupId>com.github.paveljakov</groupId>
    <artifactId>queryless-plugin-maven</artifactId>
    <version>${queryless.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
                <sources>
                    <param>queries/*.sql</param>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>

Or simple Gradle plugin configuration (kotlin):

plugins {
    id("com.github.paveljakov.plugin") version("${queryless.version}")
}

queryless {
    sources = fileTree("src/main/resources/queries").matching {
        include("**/*.sql")
    }
}

Would produce autogenerated Java source file:

// Generated by Queryless (https://github.com/paveljakov/queryless)
package queryless.generated;

import java.lang.String;
import javax.annotation.Generated;

/**
 * <i>Queryless query bundle.</i><br/><h1>Queries</h1>
 */
@Generated(
    value = "Generated by Queryless (https://github.com/paveljakov/queryless)",
    date = "2019-01-02T23:01:32.339"
)
public final class Queries {
  /**
   * <h2>Query text:</h2><pre>{@code -- Finds employees by ID
   * SELECT
   *     ID,
   *     NAME,
   *     AGE,
   *     DEPARTMENT
   * FROM
   *     EMPLOYEE
   * WHERE
   *     ID = :id}</pre>
   */
  public static final String EMPLOYEE_FIND = "-- Finds employees by ID\n"
      + "SELECT\n"
      + "    ID,\n"
      + "    NAME,\n"
      + "    AGE,\n"
      + "    DEPARTMENT\n"
      + "FROM\n"
      + "    EMPLOYEE\n"
      + "WHERE\n"
      + "    ID = :id";

  private Queries() {
  }
}

This class could be used like this:

jdbcTemplate.queryForObject(Queries.EMPLOYEE_FIND, params, Employee.class);

And in Intellij or Eclipse (or STS) IDE it would look like this:

Intellij IDEA

Eclipse IDE

Basic usage

To use Queryless Maven/Gradle plugin you just need to add plugin declaration to your build script and configure source query files location(s).

Maven plugin

<plugin>
    <groupId>com.github.paveljakov</groupId>
    <artifactId>queryless-plugin-maven</artifactId>
    <version>${queryless.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <phase>generate-sources</phase>
        </execution>
    </executions>
</plugin>

Gradle plugin

Not yet published in cntral repo.

Kotlin:

plugins {
    id("com.github.paveljakov.plugin") version("${queryless.version}")
}

Groovy:

plugins {
    id 'com.github.paveljakov.plugin' version '${queryless.version}'
}

Basic configuration

Minimal configuration plugin needs is query source files location(s) configuration.

Maven configuration

<configuration>
    <sources>
        <param>**/*.sql</param>
    </sources>
</configuration>

Gradle configuration

Kotlin:

queryless {
    sources = fileTree("src/main/resources").matching {
        include("**/*.sql")
    }
}

Groovy:

queryless {
    sources = fileTree('src/main/resources') {
        include '**/*.sql'
    }
}

Advanced usage

todo

Query bundles

todo

Nested query bundles

todo

Advanced configuration

todo

Considerations

todo

Other projects

Versions

Version
1.0.2
1.0.1
1.0.0