-
Notifications
You must be signed in to change notification settings - Fork 52
Ru:criteria
(это еще не законченная статья, пожалуйста не надо в нее вставлять куски больших непонятных примеров со всякими вспомогательными классами Debug и т.п. Однако подправка логических ошибок, опечаток и т.д. приветствуется ;) )
Criteria - класс, позволяющий получать список бизнес объектов, единичный объект, списки полей полей объектов или производные полей. В отличие от просто OSQL Criteria больше оперирует в условиях не полями таблицы, а именно property'ями объектов.
Простейшее получение списка всех бизнес-объектов класса MyBook:
<?php
Criteria::create(Actor::dao())->getList();
?>
SQL запрос в базу при этом будет следующий:
SELECT id, name, country, childs, best_film_id FROM actor;
Критерии поддерживают возможность выборки объектов по параметрам. Для этого в критерию через метод add нужно добавить какой-либо LogicalObject. Например необходимо получить всех актеров, живущих в США:
<?php
Criteria::create(Actor::dao())->
add(Expression::eq('country', DBValue::create('USA')))->
getList();
?>
Запрос в базу будет иметь вид:
SELECT id, name, country, childs, best_film_id FROM actor WHERE country = 'USA';
При добавление в Criteria нескольких LogicalObject в SQL отношение между ними определяется через логический оператор AND
Так же в условиях выборки объектов могут участвовать параметры связанных объектов. Например, можно получить список всех актеров у которых лучший фильм был титаник:
<?php
Criteria::create(Actor::dao())->
add(Expression::eq('bestFilm.name', DBValue::create('Titanic')))->
getList();
?>
SQL запрос:
SELECT id, name, country, childs, best_film_id
FROM actor
JOIN film ON actor.best_film_id = film.id
WHERE film.name = 'Titanic';
Список объектов можно получать отсортированным по условиям. Для этого у Criteria используется метод addOrder в который обычно передается объект OrderBy, либо строка, которая оборачивается в OrderBy. Для примера можно получить всех актеров начинающихся с буквы J и отсортировать их пол алфавиту:
<?php
Criteria::create(Actor::dao())->
add(Expression::like('name', DBValue::create('J%')))->
addOrder(OrderBy::create('name'))->
getList();
?>
SQL запрос:
SELECT id, name, country, childs, best_film_id FROM actor WHERE name like 'J%' ORDER BY name;
При использовании нескольких условий сортировки в SQL порядок этих условий соответствует порядку добавления соотвествющих условий в Criteria
Бывают случаи когда необходимо получить не объект, а лишь несколько полей или какие-то агрегатные значения от этих полей. В таких случаях используется метод addProjection. Например посчитать число ролей во всех фильмах, вышедших в 2009 году.
<?php
$rolesCount2009 = Criteria::create(Actor::dao())->
addProjection(Projection::count('id', 'count'))->
add(Expression::eq('roles.film.year', DBValue::create('2009')))->
getCustom('count');
?>
SQL запрос:
SELECT count(actor.id) as "count"
FROM actor
JOIN role ON actor.id = role.actor_id
JOIN film ON role.film_id = film.id
WHERE film.year = '2009';
Примечания:
- Запросы в базу упрощены, из них убраны кавычки и алиасы. В реальных запросах генерируемых через критерию каждой таблице задается уникальный алиас и все используемые поля таблиц имеют алиас (мета будет написана и добавлена чуть позже для удобства отдельной страницей).
- Подсмотреть выдуманную мету для объектов из примеров можно здесь. Мета,объекты и структура базы не претендуют на продуманность, а лишь спроектированы таким образом, что бы примеры были наиболее наглядны и просты.