Querying Model Classes
The previous documentation outlined how to use ::fetch()
on a model class to fetch by primary key, but the majority of cases will most likely require queries to fetch collections of model classes.
query() or queryOne()
All classes that extend ModelClass
can call the static methods query()
or queryOne()
. The difference is that query()
returns an array of classes and queryOne()
will return a single model class or null.
Calling either with no arguments will return every single row in that object's represented database table - or the first result (in the case of queryOne()
).
For these examples, we'll keep in line with previous articles and use the User
class example.
/** @var User[] $allUsers */
$allUsers = User::query();
/** @var User $user */
$user = User::queryOne();
Column Queries
To perform a more MySQL-like query on the columns of the model class, you can provide the columnQuery
named argument. This introduces the use of the ColumnQuery
Nox ORM class.
ColumnQuery
objects have the following methods that you can call.
public function startConditionGroup(): this;
public function endConditionGroup(): this;
public function and(): this;
public function or(): this;
public function where(
string $columnName,
string $condition,
mixed $value,
bool $raw = false,
): this;
Let's look at example of using where
to query all accounts with a given email.
use Nox\ORM\ColumnQuery
/** @var User[] $allUsers */
$allUsers = User::query(
columnQuery: (new ColumnQuery())
->where("email","=","example1@example.com"),
);
Alternatively, we can change the condition
argument (the "=" argument) to "LIKE" and use the MySQL LIKE syntax. We'll use this to find any emails that contain @gmail.com
use Nox\ORM\ColumnQuery
/** @var User[] $allUsers */
$allUsers = User::query(
columnQuery: (new ColumnQuery())
->where("email","LIKE","%@gmail.com"),
);
You can chain method calls on the ColumnQuery object with the other methods available.
use Nox\ORM\ColumnQuery
/** @var User[] $allUsers */
$allUsers = User::query(
columnQuery: (new ColumnQuery())
->where("email","LIKE","%@gmail.com")
->or()
->where("email", "LIKE", "%@outlook.com"),
);
Finally, condition groups are simply sets of MySQL syntax wrapped in parentheses.
use Nox\ORM\ColumnQuery
/** @var User[] $allUsers */
$allUsers = User::query(
columnQuery: (new ColumnQuery())
->startConditionGroup()
->where("email","LIKE","%@gmail.com")
->and()
->where("username", "LIKE", "%james%")
->endConditionGroup()
->or()
->where("username","=","nox")
);
That would be the equivalent of a MySQL WHERE clause that looks like this
WHERE (email LIKE "%@gmail.com" AND username LIKE "%james%") OR username = "nox"
Result Ordering & Pagination
The query() static also has two other named parameters that can be provided as arguments. resultOrder
and pager
.
$perPage = 10;
$pageNumber = 1;
/** @var User[] $allUsers */
$allUsers = User::query(
columnQuery: (new \Nox\ORM\ColumnQuery())
->where("email","=","example1@example.com"),
resultOrder: (new \Nox\ORM\ResultOrder())
->by("id", "ASC"),
pager: (new \Nox\ORM\Pager(
pageNumber: $pageNumber,
limit: $perPage,
)),
);
Counting Results
Instead of calling query()
and then using PHP's count()
, you should instead use the ::count()
static method of a ModelClass
- as this uses MySQL's own COUNT()
function - which is quicker than having MySQL return every row in your requested query.
count()
allows you to provide the columnQuery
named argument as shown in query examples above.
$numUsersWithEmails = User::count(
columnQuery: (new \Nox\ORM\ColumnQuery())
->where("email","IS NOT",null),
);
Saving Entire Collections
Implementations that extend the ModelClass allow you to use the available method of save()
. However, sometimes you need to mass save a bunch of objects and running multiple queries isn't always the best option. A single query is more efficient. ::saveAll()
allows you to provide it an array of ModalClass instances that will be compiled down into a single MySQL query set and saved all at once.
$user1 = ?; // Some instance of User which extends ModelClass
$user2 = ?;
$user3 = ?;
User::saveAll([$user1, $user2, $user3]);