Инструменты пользователя

Инструменты сайта


limb3_2007_2:ru:usage:active_record:crud

Создание, сохранение, загрузка и удаление объектов

Итак, ActiveRecord - это посредник между клиентским кодом и одной записью одной таблицы базы данных.

Таблицы базы данных

В процессе описания, мы будем опираться на класс User и таблицу user, с которыми мы работали в примере на странице "Краткое описание".

Итак, таблица user содержит автоинкрементное поле id. Это суррогатный первичный ключ. Его наличие обязательно во всех таблицах, с которыми вы работаете через класс lmbActiveRecord.

lmbActiveRecord пытается самостоятельно определить, с какой таблицей стоит работать по названию класса. Если мы создали дочерний класс BasePlan, тогда по-умолчанию этот класс будет работать с таблицей base_plan. То есть название класса преобразуется из StudlyCaps в under_scores.

Вы можете самостоятельно задать имя таблицы, с которой следует работать дочернему классу посредством определения атрибута $db_table_name :

class User extends lmbActiveRecord
{
  protected $_db_table_name = 'my_user';
}

lmbActiveRecord использует в своей работе класс lmbTableGateway, который обеспечивает все низкоуровневневые операции по считыванию и записи данных из соотвествующей таблицы базы данных. Также lmbTableGateway считывает информацию о структуре таблицы, о типах полей и обеспечивает фильтрацию полей, когда это необходимо.

Создание и заполнение объектов

Можно заполнять объекты по одному полю, например:

  $user = new User();
  $user->setName('Vasa');
  $user->setLastName('Pupkin');
  $user->getName();        // Выведет Vasa
  $user->getLastName();   // Выведет Pupkin
 

или так:

  $user = new User();
  $user->set('name', 'Vasa');
  $user->set('last_name', 'Pupkin');
  $user->get('name');        // Выведет Vasa
  $user->get('last_name');   // Выведет Pupkin

Также можно передавать массив данных прямо в конструктор:

  $data = array('name' => 'Vasa', 
                'last_name' => 'Pupkin');
  $user = new User($data);

Для заполнения и получения данных из объектов можно также использовать методы import() и export(). В качестве агрумента метода import() можно использовать массив, другой объект ActiveRecord или любой иной контейнер данных, который поддерживает метод export(), например, запись из базы данных или же объект класса lmbDataspace, например:

  $user1 = new User();
  $user1->import(array('name' => 'Vasa', 'last_name' => 'Pupkin'));
 
  $user2 = new User();
  $user2->import(lmbDataspace(array('name' => 'Vasa', 'last_name' => 'Pupkin')));
 
  $other_user = new User(array('name' => 'Vasa', 'last_name' => 'Pupkin'));
  $user3 = new User();
  $user3->import($other_user);

Сохранение объектов

Метод lmbActiveRecord :: save() создает в таблице новую запись, если объект является новым. По-умолчанию объект является новым, если у него еще нет идентификатора (значения в поле id) . Если объект уже существует, когда при вызове save() запись будет обновлена.

Метод lmbActiveRecord :: save() возвращает идентификатор созданной или измененной записи.

$user = new User();
$user->setName('Vasa');
$user->save(); // Вернет сгенерированный идентификатор.

Для получения информации, является ли объект новым, можно использовать метод lmbActiveRecord :: isNew(). Метод lmbActiveRecord :: isDirty() возвращает true, если объект содержит данные, которых еще нет в базе данных (новые или изменение в процессе работы после загрузки). При помощи метода lmbActiveRecord :: isDirtyProperty($property_name) можно узнать, была ли изменено определенное поле. Все это лучше продемонстрировать небольшим куском кода:

$user = new User();
$user->setName('Vasa');
$user->isNew();  // Вернет true
$user->isDirty();  // Вернет true
$user->save();
 
$user->isDirty();  // Вернет false
$user->isNew();  // Вернет false
 
$user->setName('Ivan');
 
$user->isNew();  // Вернет false
$user->isDirty();  // Вернет true
 
$user->save();
$user->isDirty();  // Вернет false

Загрузка объектов

Для загрузки ранее сохраненного объекта по имеющемуся идентификатору можно использовать передачу этого идентификатора в конструктор, например:

  $user = new User($user_id);

Если запись с таким идентификатором не будет найдена, будет сгенерировано исключение класса lmbARException. Например:

try{
$user = new User(-100);
}
catch(lmbARException $e){
 addError('Cant load object!');
}

Также можно использовать статический метод lmbActiveRecord :: findById($class_name, $id):

  $user = lmbActiveRecord :: findById('User', $user_id);

Если запись с указанным идентификатором не будет найдена, также будет сгенерировано исключение класса lmbARException, как и в случае передачи идентификатора в конструктор.

К сожалению, в PHP пока практически невозможно сделать нечто подобное $user = User :: findById($user_id) (то есть получить именно объект класса User) без применения средств автогенерации.

Третий вариант загрузки метод lmbActiveRecord :: loadById($id), например:

  $user = new User();
  $user->loadById($user_id);

Наше личное мнение заключается в том, что нужно все же использовать статический метод findById вместо loadById(тем более, что внутри loadById реализован через findById).

Если вам нужно загрузить объект по какому-либо условию, можно воспользоваться методом lmbActiveRecord :: findFirst($class_name, $params = array()). В качестве аттрибута второго параметра criteria можно передавать чаcть SQL-запроса или объект из набора Criteria. Также можно задать правила сортировки, используя аттрибут sort, передав ассоциативный массив где ключ - поле, а значение - способ сортировки. Например:

  $criteria = new lmbSQLFieldCriteria('name', '%Vasa%', lmbSQLFieldCriteria :: LIKE);
  $sort = array('name' => 'DESC', 'last_name' => 'ASC');
  $user = lmbActiveRecord :: findFirst('User', array('criteria' => $criteria, 'sort' => $sort));

Универсальный статический метод lmbActiveRecord :: find($class, $params = array()) используется для загрузки сразу нескольких объектов с возможностью применения сортировки и фильтрации по некоторому условию. Метод find() возвращает итератор c объектами. То есть, с каждым элементов можно работать, как с полноценным объектом класса lmbActiveRecord.

Подробнее о различных find()-методах будет рассказано в соответствующем разделе "Поиск и сортировка объектов".

Удаление

Для удаления записи из таблицы используется метод lmbActiveRecord :: destroy(). Этот метод используется если объект уже был загружен или же он имеет идентификатор, например, проставленный вручную, например:

  $user = new User($user_id);
  $user->destroy();
 
  $user = new User();
  $user->setId($user_id);
  $user->destroy();

Для удаления нескольких объектов используется статический метод lmbActiveRecord :: delete($class, $params = array()). В качестве аттрибута criteria второго аргумента можно передавать часть SQL-запроса, или же объект одного из классов Criteria. Например:

  lmbActiveRecord :: delete('User', 'id=100');
  lmbActiveRecord :: delete('User', new lmbSQLFieldCriteria('name', '%Vasa%', lmbSQLFieldCriteria :: LIKE));

Если критерий не задан, то будут удалены все объекты заданного класса.

  lmbActiveRecord :: delete('User'); //удалит все объекты User

Обратите внимание, что при использовании метода delete() объекты не будут удалены одним DELETE запросом. Объекты будут загружены из базы данных при помощи find() метода и удалены по-одному. Это сделано для того, чтобы обеспечивать целостность данных при наличии какой-либо бизнес-логики при удалении и в случае, если ваши ActiveRecord-ы находятся в различных отношениях. Если вам необходимо обеспечивать быстрое удаление без дополнительных проверок, этот код нужно будет создавать вручную.

Обсуждение

Ваш комментарий. Вики-синтаксис разрешён:
     __  ____   _____  ____   ___ 
 __ / / / __ \ / ___/ /_  /  / _ )
/ // / / /_/ // (_ /   / /_ / _  |
\___/  \____/ \___/   /___//____/
 
limb3_2007_2/ru/usage/active_record/crud.txt · Последние изменения: 2010/11/10 10:02 (внешнее изменение)