Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

A lightweight, fluent Java library for building parameterized SQL queries and filtering in-memory data, no runtime dependencies required.


## Features

- Fluent, readable builder API for SELECT, INSERT, UPDATE, DELETE, and CREATE TABLE
Expand All @@ -14,6 +15,7 @@ A lightweight, fluent Java library for building parameterized SQL queries and fi
- Subquery support: `WHERE col IN (SELECT ...)`, `WHERE EXISTS (SELECT ...)`, `WHERE NOT EXISTS`, derived-table `FROM (SELECT ...) AS alias`, JOIN subqueries, and scalar `(SELECT ...) AS alias` in SELECT
- Column selection, `DISTINCT`, `GROUP BY`, `ORDER BY`, `LIMIT`, and `OFFSET`
- SQL dialect support: Standard, MySQL, SQLite
- **Global and per-query configuration of defaults (e.g., dialect, columns, limit, LIKE wrapping) via `QueryBuilderDefaults`**
- In-memory filtering via `QueryableStorage`
- Zero runtime dependencies, pure Java 21+

Expand Down Expand Up @@ -391,6 +393,48 @@ new SelectBuilder()
.build(); // → SqlResult
```


## Global and Per-Query Configuration

You can preset the default SQL dialect, default columns, limit, offset, and LIKE wrapping for all queries using `QueryBuilderDefaults`. This is useful for enforcing a project-wide dialect (e.g., always use SQLite) or customizing builder defaults.

### Set SQLite as the default dialect for all queries

```java
import com.github.ezframework.javaquerybuilder.query.QueryBuilderDefaults;
import com.github.ezframework.javaquerybuilder.query.sql.SqlDialect;

// Set at application startup:
QueryBuilderDefaults.setGlobal(
QueryBuilderDefaults.builder()
.dialect(SqlDialect.SQLITE)
.build()
);

// All new QueryBuilder, SelectBuilder, and DeleteBuilder instances will use SQLite quoting by default:
SqlResult result = new QueryBuilder()
.select("id", "name")
.from("users")
.buildSql();
// → SELECT id, name FROM "users"
```

### Override per query

You can override the defaults for a single query using `.withDefaults()`:

```java
SqlResult result = new QueryBuilder()
.withDefaults(QueryBuilderDefaults.builder(QueryBuilderDefaults.global())
.dialect(SqlDialect.MYSQL)
.build())
.from("users")
.buildSql();
// → SELECT * FROM `users`
```

See the Javadoc for [`QueryBuilderDefaults`](src/main/java/com/github/ezframework/javaquerybuilder/query/QueryBuilderDefaults.java) for all configurable options.

## SQL Dialects

By default, `buildSql(table)` uses `SqlDialect.STANDARD` (no identifier quoting). Pass a second argument to use a different dialect:
Expand Down
58 changes: 53 additions & 5 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: API Reference
nav_order: 10
nav_order: 11
description: "Complete public method tables for every class and interface in JavaQueryBuilder"
---

Expand Down Expand Up @@ -70,8 +70,10 @@ Main entry point for SELECT queries and static gateway to DML builders.
| `offset(int n)` | `QueryBuilder` | Set `OFFSET` |
| `build()` | `Query` | Build a `Query` object (no SQL rendered yet) |
| `buildSql()` | `SqlResult` | Render SELECT using table set via `from()`, standard dialect |
| `buildSql(SqlDialect)` | `SqlResult` | Render SELECT using table set via `from()`, specified dialect |
| `buildSql(String table)` | `SqlResult` | Render SELECT for explicit `table`, standard dialect |
| `buildSql(String table, SqlDialect)` | `SqlResult` | Render SELECT for explicit `table` and dialect |
| `withDefaults(QueryBuilderDefaults)` | `QueryBuilder` | Set per-instance configuration defaults; throws `NullPointerException` if `null` |

---

Expand All @@ -91,6 +93,8 @@ Lower-level SELECT builder that produces `SqlResult` directly (no `Query` interm
| `orderBy(String col, boolean asc)` | `SelectBuilder` | Add `ORDER BY` |
| `limit(int n)` | `SelectBuilder` | Set `LIMIT` |
| `offset(int n)` | `SelectBuilder` | Set `OFFSET` |
| `withDefaults(QueryBuilderDefaults)` | `SelectBuilder` | Set per-instance configuration defaults; throws `NullPointerException` if `null` |
| `build()` | `SqlResult` | Render SELECT using defaults dialect |
| `build(SqlDialect)` | `SqlResult` | Render SELECT with given dialect |

---
Expand Down Expand Up @@ -134,6 +138,7 @@ Lower-level SELECT builder that produces `SqlResult` directly (no `Query` interm
| `whereIn(col, List<?>)` | `DeleteBuilder` | `WHERE col IN (...)` (AND); throws `IllegalArgumentException` if list is null/empty |
| `whereNotIn(col, List<?>)` | `DeleteBuilder` | `WHERE col NOT IN (...)` (AND); throws `IllegalArgumentException` if list is null/empty |
| `whereBetween(col, from, to)` | `DeleteBuilder` | `WHERE col BETWEEN ? AND ?` (AND) |
| `withDefaults(QueryBuilderDefaults)` | `DeleteBuilder` | Set per-instance configuration defaults; throws `NullPointerException` if `null` |
| `build()` | `SqlResult` | Render with standard dialect |
| `build(SqlDialect)` | `SqlResult` | Render with specified dialect |

Expand Down Expand Up @@ -242,7 +247,7 @@ getters and setters; setters are used exclusively by the builders.
|--------|-------------|
| `JoinClause(Type, String table, String on)` | Plain-table join |
| `JoinClause(Type, Query subquery, String alias, String on)` | Subquery (derived-table) join |
| `getType()` | `JoinClause.Type` `INNER`, `LEFT`, `RIGHT`, or `CROSS` |
| `getType()` | `JoinClause.Type`: `INNER`, `LEFT`, `RIGHT`, or `CROSS` |
| `getTable()` | Table name for plain-table join; `null` for subquery join |
| `getSubquery()` | Subquery for derived-table join; `null` for plain-table join |
| `getAlias()` | Alias for derived-table join |
Expand Down Expand Up @@ -279,9 +284,9 @@ public interface QueryableStorage {

| Member | Description |
|--------|-------------|
| `STANDARD` | ANSI SQL no identifier quoting |
| `MYSQL` | MySQL back-tick quoting; DELETE LIMIT supported |
| `SQLITE` | SQLite double-quote quoting; DELETE LIMIT supported |
| `STANDARD` | ANSI SQL (no identifier quoting) |
| `MYSQL` | MySQL: back-tick quoting; DELETE LIMIT supported |
| `SQLITE` | SQLite: double-quote quoting; DELETE LIMIT supported |
| `render(Query)` | Render a SELECT query to `SqlResult` |
| `renderDelete(Query)` | Render a DELETE query to `SqlResult` |

Expand All @@ -296,6 +301,49 @@ public interface QueryableStorage {

---

## configuration

### `QueryBuilderDefaults`

Immutable configuration object. See [Configuration](configuration) for a full
usage guide.

**Static methods**

| Method | Returns | Description |
|--------|---------|-------------|
| `global()` | `QueryBuilderDefaults` | Current JVM-wide defaults instance |
| `setGlobal(defaults)` | `void` | Replace the JVM-wide defaults; throws `NullPointerException` if `null` |
| `builder()` | `Builder` | New builder pre-filled with canonical defaults |
| `builder(source)` | `Builder` | New builder copied from `source`; throws `NullPointerException` if `null` |

**Instance getters**

| Method | Returns | Description |
|--------|---------|-------------|
| `getDialect()` | `SqlDialect` | Configured SQL dialect |
| `getDefaultColumns()` | `String` | Default SELECT column expression |
| `getDefaultLimit()` | `int` | Default LIMIT; `-1` means none |
| `getDefaultOffset()` | `int` | Default OFFSET; `-1` means none |
| `getLikePrefix()` | `String` | Prefix for LIKE values |
| `getLikeSuffix()` | `String` | Suffix for LIKE values |

---

### `QueryBuilderDefaults.Builder`

| Method | Returns | Description |
|--------|---------|-------------|
| `dialect(SqlDialect)` | `Builder` | Set dialect; throws `NullPointerException` if `null` |
| `defaultColumns(String)` | `Builder` | Set default SELECT columns; throws `NullPointerException` if `null` |
| `defaultLimit(int)` | `Builder` | Set default LIMIT; pass `-1` to disable |
| `defaultOffset(int)` | `Builder` | Set default OFFSET; pass `-1` to disable |
| `likePrefix(String)` | `Builder` | Set LIKE prefix; throws `NullPointerException` if `null` |
| `likeSuffix(String)` | `Builder` | Set LIKE suffix; throws `NullPointerException` if `null` |
| `build()` | `QueryBuilderDefaults` | Build the immutable configuration object |

---

## exception

### `QueryBuilderException`
Expand Down
6 changes: 3 additions & 3 deletions docs/conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ description: "Operators, Condition, ConditionEntry, Connector AND/OR, and the or

## Overview

Every `where*` call on a builder creates a `ConditionEntry` — a triple of:
Every `where*` call on a builder creates a `ConditionEntry` with three properties:

- a **column name** (or `null` for EXISTS subquery conditions)
- a **`Condition`** (operator + value)
Expand Down Expand Up @@ -84,7 +84,7 @@ constant and the SQL it generates.

## AND vs OR connector

### Default AND
### Default behavior (AND)

All `where*` methods use `AND`:

Expand All @@ -96,7 +96,7 @@ new QueryBuilder()
// → WHERE role = ? AND active = ?
```

### OR — use the `orWhere*` variant
### OR conditions

```java
new QueryBuilder()
Expand Down
Loading
Loading