Skip to main content

Queries

Ormed has a few ways to reach the database because a list screen, a model mutation, and a transaction have different responsibilities. Pick the smallest layer that matches the job, then move to a lower layer when you need more control.

Pick an API by the job​

If you need to...UseWhy
Compose filters, joins, projections, or aggregatesQuery BuilderControls the shape of a typed read or write without hiding the SQL work
Insert, update, delete, or upsert a modelRepositoryKeeps model-centric mutations and persistence rules together
Initialize connections, run transactions, or route databasesDataSourceOwns connection lifecycle and the boundary around multiple operations
Explore a table or run SQL before you have a modelDirect Database AccessLets you start with the schema and add generated models when they become useful

A common request flow​

This example shows the usual split: the query builder reads a shaped result, while a repository handles a model write. The generated model and query definitions come from the model setup described in Defining Models.

Future<void> introQueryExample(DataSource dataSource) async {
// Query with fluent API
final users = await dataSource
.query<$User>()
.whereEquals('active', true)
.orderBy('createdAt', descending: true)
.limit(10)
.get();

// Repository operations
final repo = dataSource.repo<$User>();
final user = await repo.find(1);
if (user != null) {
user.setAttribute('name', 'John');
await repo.update(user);
}
}

For a multi-step change, put the read and write operations inside a transaction so they succeed or fail together. Keep connection setup in the DataSource; keep filtering and projections close to the query that needs them.

Choose a starting path​

  • Listing, searching, or reporting: start with the Query Builder. Add joins, predicates, ordering, pagination, or projections as the screen requires.
  • CRUD around a model: start with the Repository. It is the clearest home for create, update, delete, and model-oriented workflows.
  • Boot, transactions, or multiple databases: start with DataSource, then call the query or repository API inside that lifecycle boundary.
  • No stable model yet: use Direct Database Access while you learn the schema. Introduce a generated model when repeated access benefits from types and shared behavior.

Learn in this order​

  1. Query Builder: core read/write fluency.
  2. Repository: structured model mutations.
  3. Loading Relations: association-aware reads.
  4. DataSource: boot, connection control, transactions.
  5. JSON Queries + Caching: specialized tuning.

Keep the boundaries clear​

The query builder controls SQL shape. The repository controls model workflow. The DataSource controls connection lifecycle and transaction scope. Keeping those responsibilities separate makes it easier to test a query, change persistence behavior, or add another database without rewriting every call site.

Start here​