{"id":30329323,"url":"https://github.com/kayr/ezy-query","last_synced_at":"2025-08-18T02:03:56.939Z","repository":{"id":41456757,"uuid":"503053626","full_name":"kayr/ezy-query","owner":"kayr","description":"Convert Your Sql Query To A Queryable Java API/Code.. think of A Queryable View In Your Code Using Java","archived":false,"fork":false,"pushed_at":"2025-08-10T17:05:12.000Z","size":758,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-18T02:02:11.742Z","etag":null,"topics":["code-generation","codegenerator","gradle","gradle-plugin","java","sql","sql-query"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kayr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-06-13T17:33:00.000Z","updated_at":"2025-08-10T17:05:15.000Z","dependencies_parsed_at":"2023-11-25T23:26:35.039Z","dependency_job_id":"af5f5b62-211d-4126-ae5f-8f9fc395fa7f","html_url":"https://github.com/kayr/ezy-query","commit_stats":{"total_commits":101,"total_committers":1,"mean_commits":101.0,"dds":0.0,"last_synced_commit":"305a0f261fe97deac9192ee2d28f43956168d245"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/kayr/ezy-query","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kayr%2Fezy-query","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kayr%2Fezy-query/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kayr%2Fezy-query/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kayr%2Fezy-query/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kayr","download_url":"https://codeload.github.com/kayr/ezy-query/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kayr%2Fezy-query/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270932693,"owners_count":24670250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-generation","codegenerator","gradle","gradle-plugin","java","sql","sql-query"],"created_at":"2025-08-18T02:02:04.404Z","updated_at":"2025-08-18T02:03:56.864Z","avatar_url":"https://github.com/kayr.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EzyQuery: Bring back the power of raw SQL in Java.\n\nEzyQuery brings the best of both worlds: SQL's expressiveness and Java's compile-time safety, making database access\nboth powerful and reliable. It is a Java library that bridges the gap between raw SQL and compile-time type-safe code.\n\nIt is lightweight with zero runtime dependencies.\n\n## Download\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.kayr/ezy-query-gradle-plugin/badge.svg?style=plastic)](https://maven-badges.herokuapp.com/maven-central/io.github.kayr/ezy-query-gradle-plugin)\n\nAdd the following to your `build.gradle` file.\n\n```groovy\nbuildscript {\n    repositories {\n        mavenCentral()\n    }\n}\n\nplugins {\n    id 'io.github.kayr.gradle.ezyquery' version '0.0.24'\n}\n```\n\n## Features\n\n1. Flexible Query fluent API e.g   `where(Q.CUSTOMER_NAME.eq(\"John\").and(Q.CUSTOMER_EMAIL.isNotNull()))`.\n2. Query Expressions e.g `.where(Cnd.expr(\"customerName = 'John' and customerEmail is not null\"))`.\n   Ideally if you are building a Rest-API then clients get a powerful filtering API by passing the expressions as a\n   parameter. The query is parsed and converted to a parameterized sql query.\n3. Named parameters. You can add named parameters to static parts of your SQL query and these will recognize.\n4. Support for CTEs.\n5. If your sql is too complex or uses unsupported features you can still use it to generate APIs for your named params.\n6. All generated sql queries are parameterized to avoid sql injection.\n7. Automatic mapping of sql result to java pojo.\n8. The same query is used to count and list data. Which makes building pagination easy and prevents the need to write\n   two queries.\n9. Sort by any field in the query. e.g `orderBy(GET_CUSTOMERS.CUSTOMER_NAME.asc())`.\n10. You can sort using a string expression. e.g `customerName asc, customerEmail desc`.\n11. Gradle plugin to generate the java code from your sql files.\n12. Maven plugin\n\n## How it works\n\nConverts your SQL query to A queryable Java API/Code... think of A Queryable View In Your Code Using Java\nThis will work for most sql queries in the\nformat `WITH ... \u003cCTE\u003e ... SELECT ... FROM ... WHERE ... JOIN ... ORDER BY ... LIMIT ... OFFSET ...`\n\n1. Write your sql query in a file ending with `.ez.sql`. in the directory `src/main/ezyquery`.\n   For better organisation consider adding the files in the similar package structure and your sources code.\n   \u003c!-- snippet:custom-queries-sql --\u003e\n   ```sql\n   -- file: customer-queries.sql\n   -- ## dynamic:get all customers\n   SELECT c.id                  as customerId_long,\n          lower(c.customerName) as customerName_string,\n          c.email               as customerEmail_string,\n          c.phone               as customerPhone,\n          c.score               as customerScore\n   FROM customers c;\n   \n   -- ##dynamic:get orders\n   SELECT o.id          as customerId_long,\n          c.cutomerName as customerName_string,\n          c.email       as customerEmail,\n          o.item        as item,\n          o.price       as price_double,\n          o.quantity    as quantity\n   FROM orders o\n            inner join customers c on c.id = o.customerId and c.membership = :membership\n   WHERE c.membership = :membership;\n   \n   -- ## static: update customer score\n   update customers c\n   set c.score = :score\n   where email = :email;\n   ```\n   \u003c!-- endsnippet --\u003e\n   The above query has two types of queries dynamic and static.\n    - **Dynamic queries**: These are pre-processed by ezy-query to allow for advanced filtering, sorting, and\n      pagination. If you prefix your query name with dynamic e.g `-- ## dynamic:get all customers` then ezy query will\n      pre-process to allow for advance feature. Only select statements can be dynamic queries.\n    - **Static queries**: These only get basic preprocessing to extract the named parameters and mostly left untouched.\n      These are useful for other types of queries for example insert, delete, update statements or any other types of\n      sql. EzyQuery will not try to validate the sql syntax like the case for dynamic queries. These are creating by\n      prefixing the name with *static:* e.g. `## static: update customer status`\n2. Run `./gradlew ezyBuild` to convert your SQL query file to a java class. This will generate a java class for you.\n   The class name will be generated based on your file name. The class `CustomerQueries` will contain two query classes\n   that can be accessed via the static methods e.g. `CustomerQueries.getAllCustomers()`. Below is a snippet of what will\n   be generated.\n   ```java\n   //This is a snippet of the generated class\n   public class CustomerQueries {\n       public static GetAllCustomers getAllCustomers() {...}\n       public static GetOrders getOrders() {...}\n       //this is generated by the get all get all customers query\n       public static class GetAllCustomers implements EzyQueryWithResult\u003cGetAllCustomers.Result\u003e {\n            ...\n            public static class Result implements DynamicFieldSetter {\n            ...\n            }\n       }\n       //this is generated by the get orders query\n       public static class GetOrders implements EzyQueryWithResult\u003cGetOrders.Result\u003e {\n            ...\n            public static class Result implements DynamicFieldSetter {\n            ...\n            }\n       }\n   }\n   ```\n3. Setup up EzySql instance that will act as an entry point to using EzyQuery. Below is an example with Hikari\n    ```java\n    var config = new HikariConfig();\n    //...\n    EzySql ezySql = EzySql.withDataSource(new HikariDataSource(config))\n    ```    \n4. You can now use the generated class to query your database with a flexible easy to use api.\n   The example below that fetches/filters/sorts customers from the db whose name is `John` and email is not null;\n   \u003c!-- snippet:how-to-use--\u003e\n   ```groovy\n           var Q = CustomerQueries.getAllCustomers()\n           var result = ezySql.from(Q)\n                   .where(Q.CUSTOMER_NAME.eq(\"john\").and(Q.CUSTOMER_EMAIL.isNotNull()))\n                   .orderBy(Q.CUSTOMER_NAME.asc(), Q.CUSTOMER_EMAIL.desc())\n                   .offset(0)\n                   .limit(10)\n                   .listAndCount()\n   \n           assert result.getCount() \u003e 0\n           assert !result.getList().isEmpty()\n           assert result.getList().get(0).getCustomerName().equals(\"john\")\n   ```\n   \u003c!-- endsnippet --\u003e\n\n## Usage\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Other features](#other-features)\n  - [Working with spring boot](#working-with-spring-boot)\n  - [Filtering](#filtering)\n  - [Sorting and pagination](#sorting-and-pagination)\n  - [Named Parameters](#named-parameters)\n  - [Executing other types of queries(INSERT/UPDATE/DELETE etc)](#executing-other-types-of-queriesinsertupdatedelete-etc)\n  - [Specifying a custom result mapper](#specifying-a-custom-result-mapper)\n  - [Adding a default where clause to a generate query](#adding-a-default-where-clause-to-a-generate-query)\n  - [Adding data types to the generated pojo.](#adding-data-types-to-the-generated-pojo)\n  - [Overriding default type mappings e.g for newer JDBC drivers.](#overriding-default-type-mappings-eg-for-newer-jdbc-drivers)\n  - [Optionally select fields to be returned.](#optionally-select-fields-to-be-returned)\n  - [Using on older versions of Gradle.](#using-on-older-versions-of-gradle)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Other features\n\n### Working with spring boot\n\nIf you are using spring boot, you can do this by creating a bean of type `EzySql` in your spring configuration. Then\ninject the bean\ninto your code using the `@Autowired` annotation.\n\n```java\n\n@Bean\npublic EzySql ezyQuery(DataSource dataSource) {\n    return EzySql.withDataSource(dataSource);\n}\n```\n\n### Filtering\n\nYou have multiple options to filter provide filters to your query:\n\n1. **Through the fluent API**\n    \u003c!--snippet:filter-with-fluent-api--\u003e \n    ```groovy\n            var Q = CustomerQueries.getAllCustomers()\n            var sql = ezySql.from(Q)\n                    .where(Q.CUSTOMER_NAME.eq(\"John\").and(Q.CUSTOMER_EMAIL.isNotNull()))\n    ```\n   \u003c!--endsnippet--\u003e\n   The above will generate the below sql query. Notice how it replaces the customer name with the full function call\n   `lower(c.customerName)`. Expressions can be as complex as you need them to be.\n    \u003c!--snippet:filter-with-fluent-api-out--\u003e \n    ```sql\n    SELECT \n      c.id as \"customerId\", \n      lower(c.customerName) as \"customerName\", \n      c.email as \"customerEmail\", \n      c.phone as \"customerPhone\", \n      c.score as \"customerScore\"\n    FROM customers c\n    WHERE (lower(c.customerName) = ? AND c.email IS NOT NULL)\n    LIMIT 50 OFFSET 0\n    ```\n    \u003c!--endsnippet--\u003e \n\n2. **Filtering with the condition API:** This one is similar to building an AST with and offers alot more predictability\n   of the resulting filter at the cost of readability(lispy style).\n    \u003c!--snippet:filter-with-condition-api--\u003e\n    ```groovy\n            var Q = CustomerQueries.getAllCustomers()\n            var sql = ezySql.from(Q)\n                    .where(Cnd.and(Cnd.eq(Q.CUSTOMER_NAME, \"John\"), Cnd.isNotNull(Q.CUSTOMER_EMAIL)))\n    ```\n   \u003c!--endsnippet--\u003e\n\n\n3. **Filtering with the ezy-query expression:** This allows you pass filter strings directly to ezy-query. This can be\n   useful where you want to allow client code to dynamically filter the data from the frontend.\n    \u003c!-- snippet:filter-with-ezy-query-expressions--\u003e\n    ```groovy\n            var Q = CustomerQueries.getAllCustomers()\n            var sql = ezySql.from(Q)\n                    .where(Cnd.expr(\"customerName = 'John' and customerEmail is not null\"))\n    ```\n   \u003c!--endsnippet--\u003e\n   **NOTE:** To use this feature you will need to add JSQLParser to your classpath. If you are using gradle you can add\n   it like this\n    ```groovy\n    dependency {\n        implementation 'com.github.jsqlparser:jsqlparser:4.8'\n    }\n    ```\n   or maven\n    ```xml\n    \n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.github.jsqlparser\u003c/groupId\u003e\n        \u003cartifactId\u003ejsqlparser\u003c/artifactId\u003e\n        \u003cversion\u003e4.8\u003c/version\u003e\n    \u003c/dependency\u003e\n    ```\n4. **Filtering with maps:** This is where you can use the java maps to build filters for a query. This is useful for\n   example when you need to pass query params from an http call directly to your query:\n   e.g `http://example.com?customerName.eg=John\u0026customerEmail.isNotNull`\n    \u003c!-- snippet:filter-with-map--\u003e\n    ```groovy\n            var Q = CustomerQueries.getAllCustomers()\n            var sql = ezySql.from(Q)\n                    .where(Cnd.fromMap(\n                            Map.of(\"customerName.eq\", \"John\",\n                                    \"customerEmail.isnotnull\", Optional.empty())))//use optional empty or null to show that we have no value here\n    ```\n   \u003c!-- endsnippet--\u003e\n   Most http server libraries use multivalue maps so there is alternate method for creating a criteria from a\n   multivalue map.\n   \u003c!-- snippet:filter-with-mv-map --\u003e\n   ```groovy\n           var Q = CustomerQueries.getAllCustomers()\n   \n           def filterMap = new HashMap\u003cString, List\u003c?\u003e\u003e()\n           filterMap.put(\"customerName.eq\", List.of(\"John\"))\n           filterMap.put(\"customerEmail.isnotnull\", Collections.emptyList())//empty list to show we have no values here\n   \n           var sql = ezySql.from(Q)\n                   .where(Cnd.fromMvMap(filterMap))\n   ```\n   \u003c!-- endsnippet--\u003e\n   *Supported map operators for a map include:\"\n   `eq,neq,like,notlike,gt,gte,lt,lte,in,notin,between,notbetween,isnull,isnotnull`\n5. **Filtering with native sql:** Sometimes there will be operations not supported by ezy-query for this case you can\n   always fall back to using native sql. Be careful with this method,\n   ***always paremetirize your variables to avoid sql injection***\n    \u003c!-- snippet:filter-with-raw-sql--\u003e\n    ```groovy\n            var Q = CustomerQueries.getAllCustomers()\n            var sql = ezySql.from(Q)\n                    .where(Cnd.sql(\"c.customerName = ? AND c.email IS NOT NULL\", \"John\"))\n    ```\n   \u003c!-- endsnippet--\u003e\n\n### Sorting and pagination\n\nSort using fields\n\u003c!-- snippet:sort-fluent --\u003e\n```groovy\n        var Q = CustomerQueries.getAllCustomers()\n        var sql = ezySql.from(Q)\n                .orderBy(Q.CUSTOMER_NAME.asc(), Q.CUSTOMER_EMAIL.desc())\n                .limit(10)\n                .offset(20)\n```\n\u003c!-- endsnippet--\u003e\n\n\nSort using strings expression\n\n\u003c!-- snippet:sort-with-string --\u003e\n```groovy\n        var Q = CustomerQueries.getAllCustomers()\n        var sql = ezySql.from(Q)\n                .orderBy(\"customerName asc, customerEmail desc\")\n                .limit(10, 20) //another alternative for pagination\n```\n\u003c!-- endsnippet--\u003e\nSort using Sort Object\n\u003c!-- snippet:sort-with-sort-object --\u003e\n```groovy\n        var Q = CustomerQueries.getAllCustomers()\n        var sql = ezySql.from(Q)\n                .orderBy(Sort.by(\"customerName\", Sort.DIR.ASC))\n```\n\u003c!-- endsnippet--\u003e\n\n### Named Parameters\n\nYou can add named parameters to static parts of your sql query and pass them at runtime. This is useful when some\nparts of the query are not necessarily dynamic e.g if you have an sql query that has derived tables that need named\nparams.\n\nName parameters are supported in the where clause, join conditions and order by clauses.\n\nGiven the following sql query.\n\n```sql\n-- file: get-customers.sql\nSELECT o.id       as customerId,\n       c.name     as customerName,\n       c.email    as customerEmail,\n       o.item     as item,\n       o.price    as price,\n       o.quantity as quantity\nFROM orders o\n         inner join customers c on c.id = o.customerId and c.membership = :membership\nWHERE c.membership = :membership\n```\n\nYou can pass the named parameter `:membership` at runtime as follows.\n\n\u003c!-- snippet:named-params --\u003e\n```groovy\n        var Q = CustomerQueries.getOrders()\n        var P = CustomerQueries.GetOrders.PARAMS\n        var sql = ezySql.from(Q)\n                .where(Q.PRICE.gt(100).and(Q.QUANTITY.lt(10)))\n                .setParam(P.MEMBERSHIP, \"GOLD\")\n```\n\u003c!-- endsnippet--\u003e\n\nThis will generate the following sql query along with the params.\n\n```sql\nSELECT o.id          as \"customerId\",\n       c.cutomerName as \"customerName\",\n       c.email       as \"customerEmail\",\n       o.item        as \"item\",\n       o.price       as \"price\",\n       o.quantity    as \"quantity\"\nFROM orders o\n         INNER JOIN customers c ON c.id = o.customerId AND c.membership = ?\nWHERE (c.membership = ?)\n  AND (o.price \u003e ? AND o.quantity \u003c ?)\nLIMIT 50 OFFSET 0\n-- params=[GOLD, GOLD, 100, 10]}\n```\n\nYou can see that the `GOLD` param has been added to the list of params.\n\n### Executing other types of queries(INSERT/UPDATE/DELETE etc)\n\nEzyquery was mainly built to provide dynamically ways to filter your data at runtime using a relatively safe and easy to\nuse API. However, you can also use it to execute any arbitrary sql query like inserts, deletes or updates. Parameters are\nextracted and made available as method calls in your query.\n\n**Example**:\n\nWhen you have the query below.\n\n   \u003c!-- snippet:update-customer-sql--\u003e\n   ```sql\n   -- ## static: update customer\n   update customers c\n   set c.score = :score\n   where email = :email;\n   ```\n   \u003c!-- endsnippet--\u003e\n\nBelow is how you would execute it using the ezy query sql utility classes.\n\n  \u003c!-- snippet:running-other-queries--\u003e\n  ```groovy\n          //set up the datasource\n          DataSource ds = new HikariDataSource(config)\n          //create the Zql instance which is a convenient api around jdbc\n          var zql = new Zql(ConnectionProvider.of(ds)\n          //var zql = ezySql.getZql() // or you can get it from EzySql instance\n  \n          var Q = CustomerQueries.updateCustomer()\n  \n          var updateCount = zql.update(\n                  Q.email(\"john@example.com\") //these functions are generated from the query param in the sql query\n                          .score(10)\n                          .getQuery())\n          assert updateCount \u003e 0\n  ```\n   \u003c!-- endsnippet--\u003e\n\n### Specifying a custom result mapper\n\nYou can specify a custom mapper to control how you want the results to be returned or mapped from the database. E.g\nInstead of returning a list of pojos you can return a list of maps. Here is an example.\n\nWe already have a built-in mapper that converts the result to a map. You can use it as follows.\n\u003c!-- snippet:mapper-to-map --\u003e\n```groovy\n        var Q = CustomerQueries.getAllCustomers()\n        List\u003cMap\u003e result = ezySql.from(Q)\n                .mapTo(Mappers.toMap())\n                .list()\n```\n\u003c!-- endsnippet--\u003e\n\n\nFor illustration purposes we will create a custom mapper that converts the result to a map. See code below.\n\u003c!-- snippet:mapper-to-map-custom --\u003e\n```groovy\n        var Q = CustomerQueries.getAllCustomers()\n        List\u003cMap\u003e result = ezySql.from(Q)\n                .mapTo((rowIndex, columns, resultSet) -\u003e {\n                    Map\u003cString, Object\u003e map = new HashMap\u003c\u003e();\n                    for (ColumnInfo column : columns) {\n                        map.put(column.getLabel(), resultSet.getObject(column.getLabel()));\n                    }\n                    return map;\n                })\n                .list();\n```\n\u003c!-- endsnippet--\u003e\n\n### Adding a default where clause to a generate query\n\nJust add a default where clause to your base sql query, then all your queries will have this where clause.\nAn example use-case is where you always want to fetch active customers\n\n```sql\n-- file: get-customer.sql\nSELECT c.id    as customerId,\n       c.name  as customerName,\n       c.email as customerEmail,\n       c.score as customerScore\nFROM customers c\nWHERE c.status = 'active'\n```\n\nThe above will add the where clause `c.status = 'active'` to all queries generated from the above query.\n\n### Adding data types to the generated pojo.\n\nThe generated result pojo by default will have all fields as `Object`.\nYou can add a data type to the generated pojo by adding a suffix to the field name aliases like below.\n\n```sql\n-- file: get-customer.sql\nSELECT c.id    as customerId_int,\n       c.name  as customerName_string,\n       c.score as customerScore_double, ....\n```\n\nWith the above sql,the generated pojo will have the following fields.\n\n```java\n... // code ommited for brevity\nprivate Integer customerId;\nprivate String customerName;\nprivate Double customerScore;\n...\n```\n\nThe supported data types are:\n\n- `int`\n- `long`\n- `double`\n- `float`\n- `string`\n- `boolean`\n- `date`\n- `time`\n- `decimal`\n- `bigint`\n- `byte`\n- `object`\n\nIf these types are not enough for you, you can add your own custom types by specifying custom type mappings in\nthe `ezy-query.properties` file.\n\nIn the root of the ezy-query source directory, create a file called `ezy-query.properties` and add the following.\n\n```properties\n# file: ezy-query.properties\n#add your custom type mappings here\n#the format is type.\u003ctype\u003e=\u003cjava type\u003e\n#e.g\ntype.customtype=java.time.LocalDate\ntype.vector=java.util.Vector\n```\n\nThen in your sql file you can use the custom type as follows.\n\n```sql\n-- file: get-customer.sql\nSELECT c.id    as customerId_customtype, -- specify the custom type\n       c.name  as customerName_string,\n       c.score as customerTags_vector,   -- specify the custom vector type\n    ....\n```\n\nThe generated pojo will have the following fields.\n\n```java\n    //.... code ommited for brevity\nprivate LocalDate customerId;\nprivate String customerName;\nprivate Vector customerTags;\n  ...\n```\n\n### Overriding default type mappings e.g for newer JDBC drivers.\n\nSome JDBC drivers may return types that are not supported by default. e.g newer mysql drivers\nreturn `java.time.LocalDate` or `java.util.LocalTime` for `date` and `time` types respectively. You can override the\ndefault mappings by specifying your own custom mappings.\n\n```properties\n# file: ezy-query.properties\ntype.date=java.time.LocalDate\ntype.time=java.time.LocalTime\n```\n\n### Optionally selecting fields to be returned.\n\n\u003c!-- snippet:optional-select-field --\u003e\n```groovy\n        var Q = CustomerQueries.getAllCustomers()\n        var result = ezySql.from(Q)\n                .select(Q.CUSTOMER_NAME, Q.CUSTOMER_EMAIL)\n                .list()\n\n        assert result.size() \u003e 0\n        assert result.get(0).customerName != null\n        assert result.get(0).customerId == null//we did not select this.. so it will be null\n```\n\u003c!-- endsnippet--\u003e\n\n### Using on older versions of Gradle.\n\nIn the future, we will support older versions. For older versions\nadd the script below as a workaround.\nThe script adds the necessary tasks to your `build.gradle` file.\n\n```groovy\n\nbuildscript {\n    repositories {\n        mavenCentral()\n    }\n    dependencies {\n        classpath \"io.github.kayr:ezy-query-codegen:\u003cversion\u003e\" //see the latest above\n    }\n}\n\ntask(\"ezyBuild\") {\n\n    def input = file(\"src/main/ezyquery\").toPath()\n    def output = file(\"build/generated/ezy/main\").toPath()\n\n    doLast {\n        if (input.toFile().exists()) {\n            Files.createDirectories(output)\n            BatchQueryGen.generate(input, output)\n        }\n    }\n}\ntask(\"ezyClean\") {\n    doLast {\n        project.delete(\"build/generated/ezy/\")\n    }\n}\n\nsourceSets {\n    main {\n        java {\n            srcDir \"build/generated/ezy/main\"\n        }\n\n    }\n    test {\n        java {\n            srcDir \"build/generated/ezy/test\"\n        }\n    }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkayr%2Fezy-query","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkayr%2Fezy-query","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkayr%2Fezy-query/lists"}