Содержание
Поиск и сортировка объектов. find()-методы lmbActiveRecord
В разделе "Создание, сохранение, загрузка и удаление объектов" мы упоминали про загрузку объектов класса lmbActiveRecord через статические find-методы. Познакомимся с ними поближе.
Поиск объектов через статические find() методы
lmbActiveRecord содержит набор статических методов, которые можно использовать для загрузки объектов из базы данных:
- find($class_name, $params = array()) - самый общий метод, используется для загрузки группы объектов (в виде списка, или итератора) .
- findFirst($class_name, $params = array()) - используется для загрузки первого найденного объекта.
- findOne($class_name, $params = array()) - алиас для findFirst().
- findById($class_name, $id, $throw_exception = true) - используется для загрузки только одного объекта с указанным идентификатором.
- findByIds($class_name, $ids, $params = array()) - используется для загрузки определенных объектов, если известны их идентификаторы.
Методы find() и findByIds() возвращают итераторы, то есть объекты, поддерживающие интерфейс lmbCollectionInterface, где каждый элемент выборки - объект ActiveRecord указанного в $class_name класса (или его дочернего, о чем будет рассказано в разделе "Поддержка наследования").
Для более сложных случаев, можно выполнять свои sql-запросы, получая при этом объекты ActiveRecord. О том, как это сделать, см. страницу Создание новых find()-методов. Выполнение своих sql-запросов.
Обратите внимание, что до момента использования итератора для получения данных(до вызова метода rewind()), запрос к базе данных еще не будет произведен, что позволяет производить некоторые модификации с sql-кодом уже после создания итератора, например, указывать параметры сортировти, ограничивать размер выборки и т.д. Об этом будет сказано ниже.
Методы findByid(), findFirst, (а также find() в некоторых случаях, о которых упонянуто ниже) возвращают единичные объекты. findById() имеет одну особенность: если запись с указанным идентификатором не будет найдена, также будет сгенерировано исключение класса lmbARNotFoundException, как и в случае передачи идентификатора в конструктор. Если вы не желаете получать исключения, тогда используейте третий параметр $throw_exception = false, например:
$user = lmbActiveRecord :: findById('User', $user_id, $throw_exception = false);
Если вы заметили, большинство find()-методов имеют в качестве агрумента массив $params. Массив $params может содержать различные значения, которые накладывают различные модификации на выборку, например:
- criteria - накладывает условие на выборку. В качестве значения может выступать строки или объект Criteria.
- offset, limit - позволяет ограничить размер выборки из базы данных.
- sort - позволяет указать порядок сортировки объектов при выборки из базы данных.
- first - позволяет выбрать только один объект.
Мы рассмотрим подробнее применение этих параметров чуть ниже.
Наложение условий на выборки
Для наложения условий на выборки можно воспользоваться параметром criteria в массиве $params:
- $users = lmbActiveRecord :: find('User', array('criteria' ⇒ «salary > 20000»)); - здесь в качестве условия выборки использована обычная строка.
- $users = lmbActiveRecord :: find('User', array('criteria' ⇒ new lmbSqlRawCriteria(«name», «Vasa»)); - теперь в качестве criteria - объект из набора Criteria
Если же кроме criteria никаких параметров использовать не предполагается, можно передать в find() метод только условие на выборку, например:
- $users = lmbActiveRecord :: find('User', «salary > 20000») - передается только условие выборки в виде строки без дополнительных параметров
- $users = lmbActiveRecord :: find('User', array(«name=? AND salary > ?», 'Bob', 200)) - передается условие выборки в виде массива, где первым элементом является строка с маркерами «?», которые будут заменены последовательно следующими элементами массива. Этот способ автоматически экранирует аргументы, подставляемые в маркеры.
- $users = lmbActiveRecord :: find('User', new lmbSqlRawCriteria(«name», «Vasa»)) - тоже самое, но теперь условием выборки является объект Criteria
- $user = lmbActiveRecord :: find('User', $user_id = 10) - вернет одного пользователя (единичный объект, а не итератор).
Ограничение размера выборки
При помощи метода paginate($offset, $limit) итератора, получаемого из find() метода, можно ограничить размер выборки, например:
$users = lmbActiveRecord :: find('User'); $users->paginate($offset = 0, $limit = 10); // Будет выбрано 10 первых пользователей
Тот же самый эффект можно получить путем передачи параметров offset и limit в массиве $params, который передается в качестве второго аргумента в метод find(), например:
$users = lmbActiveRecord :: find('User', array('offset' => 0, 'limit' => 10));
Если offset равен нулю, тогда в этом случае это можно опускать, то есть:
$users = lmbActiveRecord :: find('User', array('limit' => 10));
Того же эффекта можно достичь, использя метод paginate() у итератора, получаемого из find()-метода, например эти два куска кода эквивалентны:
$users = lmbActiveRecord :: find('User', array('offset' => 10, 'limit' => 10)); $users = lmbActiveRecord :: find('User'); $users->paginate($offset = 10, $limit = 10);
Для возврата только первого объекта можно использовать параметр first, например:
$user = lmbActiveRecord :: find('User', array('first')); // Будет выбран только первый пользователь
Использование параметра first эквивалентно вызову другого статического метода lmbActiveRecord :: findFirst().
Сортировка объектов при загрузке
В массив $params find()-методов можно передавать параметр sort, который позволяет установить порядок сортировки объектов при разрузке. sort - это массив вида ('поле1' ⇒ 'тип сортировки1', 'поле2' ⇒ 'тип сортировки2'), например:
$user = lmbActiveRecord :: find('User', array('sort' => array('name' => 'DESC', 'last_name' => 'ASC')));
Сортировка по-умолчанию
Если параметры сортировки в find()-методе не указаны, тогда в выборках применяются параметры сортировки по-умолчанию.
Параметры сортировки по-умолчанию задаются в классе через защищенный атрибут $_default_sort_params. В классе lmbActiveRecord он прописан как array(’id’ ⇒ ‘ASC’), то есть при выборках элементы всегда сортируются по идентификатору.
Вы можете указать другие параметры сортировки по-умолчанию:
class User extends lmbActiveRecord { protected $_default_sort_params = array('last_name' => 'ASC'); }
Сортировка после получения итератора
Параметры сортировки можно применять и после создания итератора, для этого можно использовать метод sort($params), например, эти два куска кода эквивалентны:
$users = lmbActiveRecord :: find('User', arary('sort' => array('name' => 'DESC')); $users = lmbActiveRecord :: find('User'); $users->sort(array('name' => 'DESC'));
При вызове метода sort() ранее установленные параметры сортировки (например, параметры сортировки по-умолчанию) будут изменены на новые.
Дополнительные методы при работе с полученными итераторами
Возможно накладывать множественные изменения на итераторы до итерации, например:
$rs = lmbActiveRecord :: find(..); $rs->sort(array('id' => 'desc'))->paginate(1, 2);
Для получения количества элементов в итераторе используется метод count():
$rs->count();
Для получения объекта по определенной позиции в выборке можно использовать метод at($position):
$users = lmbActiveRecord :: find('User'); $user = $users->at($position = 2);
Обратите внимание, что каждый вызор at() приводит к отдельному запросу к базе данных и эквивалентен по сути вызову метода paginate($offset = $position, $limit = 1);

Обсуждение