Khadem ORM & Schema
Complete guide to the Khadem Object-Relational Mapping system, Schema Builder, Query Builder, and relationship management for Dart applications.
SchemaBuilder
The SchemaBuilder
class provides methods for creating and managing database schemas using the Blueprint
class for table definitions.
create()
Creates a new table with the specified structure using a Blueprint
callback.
// Creating a users table
Khadem.db.schemaBuilder.create('users', (Blueprint table) {
table.id();
table.string('name');
table.string('email');
table.string('password');
table.timestamps();
});
Parameters:
tableName
: The name of the table to createcallback
: A function that defines the table structure using aBlueprint
createIfNotExists()
Creates a table only if it does not already exist.
// Creating a table if it doesn't exist
Khadem.db.schemaBuilder.createIfNotExists('posts', (Blueprint table) {
table.id();
table.string('title');
table.text('content');
table.bigInteger('user_id');
table.timestamps();
});
drop()
Drops a specified table from the database.
// Dropping a table
Khadem.db.schemaBuilder.drop('users');
dropIfExists()
Drops a table if it exists.
// Dropping a table if it exists
Khadem.db.schemaBuilder.dropIfExists('posts');
QueryBuilder
The QueryBuilderInterface
provides a fluent interface for building and executing SQL queries, supporting operations like select, insert, update, and delete.
select()
Specifies columns to retrieve in the query.
// Selecting specific columns
final users = await Khadem.db.table('users').select(['id', 'name', 'email']).get();
Parameters:
columns
: List of column names to select
Returns: QueryBuilderInterface
for method chaining
where()
Adds a WHERE clause to the query.
// Adding a WHERE clause
final user = await Khadem.db.table('users').where('email', '=', 'test@example.com').first();
Parameters:
column
: Column nameoperator
: Comparison operator (e.g., '=', '>', '<')value
: Value to compare against
get()
Executes the query and returns all matching results as a list of type T
.
// Fetching all users
final users = await Khadem.db.table('users').get();
// Fetching with conditions
final activeUsers = await Khadem.db.table('users').where('status', '=', 'active').get();
insert()
Inserts a new record into the table.
// Inserting a new user
final id = await Khadem.db.table('users').insert({
'name': 'John Doe',
'email': 'john@example.com',
'password': 'hashed_password',
});
Parameters:
data
: Map of column names to values
paginate()
Fetches a paginated list of results.
// Paginating users
final result = await Khadem.db.table('users').paginate(perPage: 10, page: 2);
print('Total: ${result.total}, Page: ${result.currentPage}');
Parameters:
perPage
: Number of items per page (default: 10)page
: Page number to fetch (default: 1)
withRelations()
Loads related models eagerly.
// Eager loading user and comments
final post = await Khadem.db.table('posts').withRelations(['user', 'comments']).first();
Parameters:
relations
: List of relation names or configurations
Relationships & Eager Loading
The framework supports eager loading of relationships through the withRelations()
method in the query builder, supporting various relation types like hasOne, hasMany, belongsTo, and belongsToMany.
withRelations()
Loads specified relationships eagerly when executing queries.
// Loading relations for models using query builder
final posts = await Khadem.db.table('posts').withRelations(['user', 'comments']).get();
Parameters:
relations
: List of relation names to load
Relation Types
The framework supports different relationship types through RelationDefinition
.
// Using relations in query builder
final posts = await Khadem.db.table('posts')
.withRelations(['user', 'comments'])
.where('published', '=', true)
.get();
Supported relation types: hasOne
, hasMany
, belongsTo
, belongsToMany
KhademModel
The KhademModel
class is the base class for all models, providing serialization, relationship management, and database operations.
Defining a Model
Extend KhademModel
to create a model with fields, relations, and database interaction.
class User extends KhademModel<User> with Timestamps, HasRelationships {
String? name;
String? email;
String? password;
User({this.name, this.email, this.password, int? id}) {
this.id = id;
}
@override
List<String> get fillable => ['name', 'email', 'password', 'created_at', 'updated_at'];
@override
List<String> get hidden => ['password'];
@override
Map<String, RelationDefinition> get relations => {
'posts': RelationDefinition<Post>(
type: RelationType.hasMany,
relatedTable: 'posts',
localKey: 'id',
foreignKey: 'user_id',
factory: () => Post(),
)
};
@override
dynamic getField(String key) {
return switch (key) {
'id' => id,
'name' => name,
'email' => email,
'password' => password,
'created_at' => createdAt,
'updated_at' => updatedAt,
_ => null
};
}
@override
void setField(String key, dynamic value) {
return switch (key) {
'id' => id = value,
'name' => name = value,
'email' => email = value,
'password' => password = value,
'created_at' => createdAt = value,
'updated_at' => updatedAt = value,
_ => null
};
}
@override
User newFactory(Map<String, dynamic> data) => User()..fromJson(data);
}
Key Properties:
fillable
: Fields that can be mass-assignedhidden
: Fields to exclude from serializationrelations
: Map of relationship definitions
Querying
Use the query
property to build queries for the model.
// Querying users using the model's query property
final users = await User().query.where('status', '=', 'active').orderBy('name').get();
Saving and Deleting
Persist or remove models using save()
and delete()
.
// Saving a model
final user = User(name: 'John', email: 'john@example.com');
await user.save();
// Deleting a model
await user.delete();
Usage Patterns
Controller Example
class UserController {
void getUsers(Request req, Response res) async {
int page = int.tryParse(req.query['page'] ?? '') ?? 1;
int perPage = int.tryParse(req.query['perPage'] ?? '') ?? 10;
final result = await Khadem.db.table('users').paginate(perPage: perPage, page: page);
res.sendJson({'users': result.data, 'total': result.total});
}
}
Relationship Example
// Using relationships with query builder
final post = await Khadem.db.table('posts')
.withRelations(['user', 'comments'])
.where('id', '=', 1)
.first();
// Accessing loaded relations
print(post?['user']?['name']);
print(post?['comments']?.length);