Skip to main content

TeaQL Quick Guide(Query)

This guide introduces the TeaQL generated query library, focusing on the two core expression families: Q and E.


1. Overview

After TeaQL generates the client library, developers can use:

  • Q: Query expressions for data access
  • E: NULL-safe chained expressions for safe navigation and evaluation

These APIs are designed to be:

  • Strongly typed
  • Fluent and readable
  • Safe for complex domain models

2. Q Expressions (Query API)

2.1 Basic Query Structure

Q.<pluralObjectName>
.<select | filter | aggregate | order | pagination>
.comment("What this query loads")
.purpose("Why this data is needed")
.executeForList(userContext)

Return a single object:

Q.<pluralObjectName>
.<select | filter | aggregate | order | pagination>
.comment("What this query loads")
.purpose("Why this data is needed")
.executeForOne(userContext)
  • executeForList(...) → returns multiple results
  • executeForOne(...) → returns a single result
  • executeForStream(...) → returns a stream for large result sets

purpose(...) is the terminal builder method. Put all select, filter, aggregation, ordering, and pagination calls before .comment(...).purpose(...).


3. Selection (Select)

3.1 Default Selection

Q.users()
.comment("Query users")
.purpose("Load data")
.executeForList(userContext);
  • Selects all fields by default

3.2 Minimal Fields

Q.usersWithMinimalFields()
.comment("Query users")
.purpose("Load user ids and versions")
.executeForList(userContext);
  • Selects only id and version

3.3 Select Variants

MethodDescription
selectSelf()Select only the object itself, no expanded references
selectAll()Select all scalar fields (no lists)
selectAny()Select all fields including lists
select<Field>()Select a single field
select<List>()Select a list field

Examples

Q.users()
.selectName()
.comment("Query users")
.purpose("Load display names")
.executeForList(userContext);

Select a related object with custom fields:

Q.orders().selectUser(
Q.usersWithIdField().selectName()
)
.comment("Query orders")
.purpose("Load orders with user names")
.executeForList(userContext);

Filter list fields during selection:

Q.users()
.selectOrderList(Q.orders().withAmountGreaterThan(100))
.comment("Query users")
.purpose("Load users with high-value orders")
.executeForList(userContext);

3.4 Unselect (Exclude Fields)

Exclude specific fields from the selection:

Q.articles()
.unselectContent()
.comment("Query articles")
.purpose("List articles without loading large content")
.executeForList(userContext);

Useful for excluding large text or blob fields.


4. Filtering

4.1 Exact Filtering (filterBy)

Q.users()
.filterByStatus("ACTIVE")
.comment("Query users")
.purpose("Load active users")
.executeForList(userContext);

Filter by object reference:

Q.orders()
.filterByUser(Q.users().withUserGenderIsFemale())
.comment("Query orders")
.purpose("Load orders for female users")
.executeForList(userContext);

4.2 Conditional Filtering (which)

Generated based on field type:

Q.users()
.withNameIsNull()
.comment("Query users")
.purpose("Find users missing names")
.executeForList(userContext);

Q.users()
.withAgeGreaterThan(18)
.comment("Query users")
.purpose("Find adult users")
.executeForList(userContext);

Generic operator form:

Q.users()
.withName(Operator.contains, "admin")
.comment("Query users")
.purpose("Find admin-like users")
.executeForList(userContext);

4.3 List Existence (has<List>)

Q.users()
.hasOrders()
.comment("Query users")
.purpose("Find users with orders")
.executeForList(userContext);

Find users who have at least one order.


5. Aggregation & Statistics

5.1 Count

Q.orders()
.count()
.comment("Query orders")
.purpose("Count orders")
.aggregation(userContext);

Conditional count with alias:

Q.orders().count(
"shippedCount",
Q.orders().withStatusAreShipped()
)
.comment("Query orders")
.purpose("Count shipped orders")
.aggregation(userContext);

5.2 Other Aggregates

Supported functions:

  • sum
  • max
  • min
  • avg

Example:

Q.orders()
.sumTotalAmount()
.comment("Query orders")
.purpose("Calculate total order amount")
.aggregation(userContext);

5.3 Group By

Q.orders()
.count()
.groupByOrderStatus()
.comment("Query orders")
.purpose("Count orders by status")
.aggregation(userContext);

6. Sorting

Sorting methods are generated per field.

Q.orders()
.orderByCreateTimeAscending()
.comment("Query orders")
.purpose("Load orders by creation time")
.executeForList(userContext);

Locale-aware sorting:

Q.users()
.orderByNameAscendingUsingGBK()
.comment("Query users")
.purpose("Load users ordered by localized name")
.executeForList(userContext);

7. Pagination

7.1 Top N

Q.orders()
.top(10)
.comment("Query orders")
.purpose("Load latest orders")
.executeForList(userContext);

7.2 Offset

Q.orders()
.offset(20, 10)
.comment("Query orders")
.purpose("Load a result window")
.executeForList(userContext);
  • Start from index 20
  • Fetch 10 records
  • Index starts from 0

7.3 Page

Q.orders()
.page(2, 20)
.comment("Query orders")
.purpose("Load page two of orders")
.executeForList(userContext);
  • Page number starts from 1
  • 20 records per page

8. E Expressions (NULL-Safe Chain API)

E provides safe navigation for deep object graphs without explicit null checks.


8.1 Safe Null Checking

CustomOrderItem item = null;

if (
E.customerOrderItem(item)
.getCustomOrder()
.getCustomer()
.getContactName()
.isNull()
) {
// your logic
}

8.2 Safe Value Evaluation

String name =
E.customerOrderItem(item)
.getCustomOrder()
.getCustomer()
.getContactName()
.eval();
  • Returns null safely if any link in the chain is null

8.3 Safe Lambda Execution

Execute logic only when value is empty:

E.customOrderItem(item)
.getCustomOrder()
.getCustomer()
.getContactName()
.whenIsEmpty(() -> {
// do something
});

Enum-specific helpers:

E.user(user)
.getGender()
.whenUserGenderIsFemale(() -> {
// do something
});

9. Summary

  • Q: expressive, composable, type-safe query DSL
  • E: NULL-safe navigation and conditional execution
  • Designed to work seamlessly with KSML domain models
  • Ideal for complex enterprise systems with deep object graphs