@@ -65,8 +65,8 @@ The interface usually delivers `stdClass` objects by default. However, you can n
6565your own data class so the data will be populated in such a class:
6666
6767```
68- $arr = $db->queryList('SELECT * FROM #__devtest', 'MyNamespace\MyDataClass');
69- $obj = $db->querySingle('SELECT * FROM #__devtest WHERE uid='.$uid, 'MyNamespace\MyDataClass');
68+ $arr = $db->queryList('SELECT * FROM #__devtest', 'MyNamespace\\ MyDataClass');
69+ $obj = $db->querySingle('SELECT * FROM #__devtest WHERE uid='.$uid, 'MyNamespace\\ MyDataClass');
7070```
7171
7272## Inserting, Updating and deleting objects
@@ -144,10 +144,10 @@ However, you can tell `DAO` your specifics:
144144
145145```
146146// Uses a specific class for the data
147- $dao = \TgDatabase\DAO($db, '#__users', 'MyNamespace\User`);
147+ $dao = \TgDatabase\DAO($db, '#__users', 'MyNamespace\\ User`);
148148
149149// Uses a specific class and another primary key attribute
150- $dao = \TgDatabase\DAO($db, '#__users', 'MyNamespace\User`, 'id');
150+ $dao = \TgDatabase\DAO($db, '#__users', 'MyNamespace\\ User`, 'id');
151151```
152152
153153` DAO ` can actually handle non-numeric primary keys. The usage is not recommended though.
@@ -251,7 +251,7 @@ That way you can further abstract data access, e.g.
251251class Users extends DAO {
252252
253253 public function __construct($database) {
254- parent::__construct($database, '#__users', 'MyNamespace\User');
254+ parent::__construct($database, '#__users', 'MyNamespace\\ User');
255255 }
256256
257257 public function findByEmail($email) {
@@ -344,6 +344,147 @@ $users = $myModel->get('users')->find();
344344
345345Imagine, how much error-proned code you would have to write yourself!
346346
347+ # Criteria API
348+ Version 1.2 introduces a basic form of ` Criteria ` which gives you more freedom to express SQL conditions
349+ when searching for rows and objects. It is designed using the Hibernate ORM Criteria template. So much
350+ of the code may appear familiar to you.
351+
352+ The Criteria API was created additional to the Data Model and DAO API and enhances it. So you can still use
353+ the v1.0 way of searching objects while already starting the Criteria API. However, it is planned to
354+ replace the ` queryList() ` and ` querySingle() ` methods in ` Database ` as well as ` count() ` and
355+ ` find() ` methods in ` DAO ` by the Criteria API in next major versions. At the moment both APIs exist
356+ independently.
357+
358+ ** Disclaimer:** The Criteria API cannot yet produce ` GROUP BY ` clauses as they are more complex to build.
359+ It will be added later.
360+
361+ ## Creating a Criteria
362+ Two ways exist: Creating a ` Criteria ` object from the ` Database ` object, or alternatively from the ` DAO `
363+ object:
364+
365+ ```
366+ // From Database object
367+ $criteria = $database->createCriteria('#__users');
368+
369+ // From DAO object
370+ $criteria = $userDAO->createCriteria();
371+ ```
372+
373+ You can define model classes (the objects returned from ` SELECT ` queries) and aliases when creating a ` Criteria ` :
374+
375+ ```
376+ // From Database object
377+ $criteria = $database->createCriteria('#__users', 'MyNamespace\\User', 'a');
378+
379+ // From DAO object
380+ $criteria = $userDAO->createCriteria('a');
381+ ```
382+
383+ As the DAO already knows about the model class, there is no need to mention it when creating from a ` DAO ` .
384+
385+ The alias is assigned to the underlying table name and will be added automatically when required in restrictions.
386+
387+ ## Using Restrictions
388+ Restrictions are expressions that can be used in ` WHERE ` clauses (and in ` JOIN ` - see below). The helper
389+ class ` Restrictions ` helps you to create them:
390+
391+ ```
392+ $expr1 = Restrictions::eq('name', 'myUsername');
393+ $expr2 = Restrictions::isNotNull('email');
394+ $criteria->add($expr1, $expr);
395+ ```
396+
397+ The most common restrictions are provided: eq, ne, lt, gt, ge, le, like, isNull, isNotNull, between. You can also
398+ use restrictions between two properties:
399+
400+ ```
401+ // Check for equalitity of name and email of a user.
402+ $expr = Restrictions::eq('name', 'email');
403+ ```
404+
405+ And it is possible to combine restrictions with ` and() ` and ` or() ` :
406+
407+ ```
408+ $expr = Restrictions::or($expr1, $expr2, $expr3);
409+ ```
410+
411+ ## Using Projections
412+ Basic projections - the aggregation of columns of different rows - are available:
413+
414+ ```
415+ $proj = Projections::rowCount();
416+ $criteria->setProjection($proj);
417+ ```
418+
419+ You will find projections for: count, distinct, sum, avg, min, max. Please notice that
420+ the returned model class is always the ` stdClass ` when using projections.
421+
422+ ## Subcriteria and JOINs
423+ This is most likely the biggest advance in using the Criteria API. The traditional API methods
424+ were not able to use subcriteria when searching for objects depending from other tables.
425+
426+ Let's assume you want to find all books in a database whose author name start with an A.
427+ The main criteria comes from books then as it is our desired model class to be returned
428+
429+ ```
430+ $criteria = $bookDAO->createCriteria('a');
431+ ```
432+
433+ Next we join the authors table and add it to the main criteria using the respective restriction
434+ to join them properly:
435+
436+ ```
437+ $authors = $authorDAO->createCriteria('b');
438+ $restriction = Restrictions::eq(array('a','author'), array('b','uid'));
439+ $criteria->addCriteria($authors, $restriction);
440+ ```
441+
442+ And finally we apply the search condition for the author:
443+
444+ ```
445+ $authors->add(Restrictions::like('name', 'A%'));
446+ ```
447+
448+ ## Getting the result
449+ That's the most easiest part:
450+
451+ ```
452+ $criteria->list();
453+ ```
454+
455+ You can set restrictions on the result:
456+
457+ ```
458+ $criteria->setFirstResult(10);
459+ $criteria->setMaxResults(20);
460+ ```
461+
462+ ## Advantages and Limitations
463+ The Criteria API will further ease in searching object in a database and return model classes, using more
464+ complex expressions and restrictions. You will be able to dynamically apply restrictions depending on
465+ the requirements of your front-end users and your application. And you won't need the DAO once you
466+ created the ` Criteria ` object. It is self-contained.
467+
468+ However, some limitations exist:
469+
470+ ' Criteria API supports basic use cases so far (searching objects with simple restrictions).
471+ * Only MySQL / MariaDB SQL dialect is produced (but can be extended to other dialects easily when you stick to the API).
472+ * GROUP BY clauses are not implemented
473+ * Multiple projections are not yet supported (such as ` SELECT MAX(name), MIN(name) FROM #__users ` ) - will be extended.
474+ * Criteria API is not yet built into DAOs to make it more exchangeable. This might break the DAO API and hence will
475+ be added in one of the next major versions.
476+ * A few of the limitations may be ovecome by using the ` SqlExpression ` and ` SqlProjection ` classes:
477+
478+ ```
479+ // Use a specific restriction not supported
480+ $myExpr = Restrictions::sql('my-sql-fragment');
481+
482+ // Use a specific projection not supported
483+ $myProj = Projections::sql('name, email');
484+ ```
485+
486+ But feel free to raise an issue (see below) when you need some extension that is not yet supported.
487+
347488# Contribution
348489Report a bug, request an enhancement or pull request at the [ GitHub Issue Tracker] ( https://github.com/technicalguru/php-database/issues ) .
349490
0 commit comments