orm PPTX, 188 КБ

advertisement
D7. ORM
Вадим Думбравану
руководитель проектов
Object-relational mapping
Недостатки текущего похода в API
• На каждую сущность программируется свой GetList,
Update, Add, Delete
• Различающийся набор параметров
• Разный синтаксис полей фильтров
• События могут быть не предусмотрены
• Разный код под разные БД (Add)
Object-relational mapping
Что мы хотим улучшить в ORM
• Однотипные операции выборки и сохранения в БД для
всех сущностей (параметры, фильтры, результаты)
• Минимальное количество кода для новых сущностей
• Стандартные события добавления/ изменения/ удаления
Object-relational mapping
Реализация
• сущности (Bitrix\Main\Entity\Base)
• поля сущностей (Bitrix\Main\Entity\Field и его наследники)
• датаменеджер (Bitrix\Main\Entity\DataManager)
use Bitrix\Main\Entity;
class CultureTable extends Entity\DataManager
{
public static function getTableName()
{
return 'b_culture';
}
public static function getMap()
{
return array(
'ID' => array(
'data_type' => 'integer',
'primary' => true,
'autocomplete' => true,
Object-relational mapping
Описание сущности
• Название сущности состоит из собственно названия
сущности и обязательного суффикса Table.
• Класс должен быть наследован от
Bitrix\Main\Entity\DataManager.
• Должны быть перекрыты два абстрактных метода
getFilePath() и getMap()
• Метод getTableName() может быть определен и должен
вернуть название таблицы. Если метод не определен, то
базовая сущность попытается получить имя таблицы
автоматически.
Object-relational mapping
Поля сущности
• Поле имеет название (соответствует БД), тип и ряд
атрибутов
• Можно указать первичный ключ
• Можно указать обязательность и маску
• Поле может быть вычисляемым
• Поле может быть ссылкой на другую сущность
'VAT_RATE_PRC' => array(
'data_type' => 'float',
'expression' => array(
'100 * %s', 'VAT_RATE'
)
),
'ORDER' => array(
'data_type' => 'Order',
'reference' => array(
'=this.ORDER_ID' =>
'ref.ID'
)
),
Object-relational mapping
Датаменеджер
•
•
•
•
•
CultureTable::update($ID, $arFields)
CultureTable::add($arFields)
CultureTable:: delete ($ID)
и наш любимый CultureTable::getList($arParams)
есть также базовый checkFields(Result $result, array $data,
$id = null)
Все методы статические. Сущность может переопределить
эти базовые методы, если это необходимо.
Object-relational mapping
Выборка данных
• Статический метод getList() с массивом параметров:
•
•
•
•
•
•
•
'select' – массив выбираемых в SELECT полей;
'filter' – массив условий фильтра для WHERE;
'group' – массив полей для группировки;
'order' – массив сортировки;
'limit' – ограничение количества записей;
'offset' – смещение начала выборки;
'count_total' – нужно ли считать количество записей
• Метод возвращает объект CDBResult старого ядра. В
ближайшем будущем метод будет возвращать объект
нового ядра DbResult.
Object-relational mapping
Выборка данных
$cultureList = CultureTable::getList(array(
'select' =>array('ID', 'NAME'),
'order' => array('NAME' =>'ASC'),
'filter'=>array('CHARSET'=>'Windows-1251'),
));
• Сортировка может быть по нескольким полям.
• Фильтр задается в расширенном синтаксисе, который
применяется в инфоблоках.
• Использование параметров, неизвестных методу,
приведет к выбросу исключения.
• Для выборки одной записи по первичному ключу может
применяться метод getById()
Object-relational mapping
Выборка данных
• Можно использовать цепочку вызовов методов объекта запроса
вместо статического метода.
$main_query = new Entity\Query(CultureTable::getEntity());
$main_query->setSelect(array('*'));
$main_query->setFilter(array('=ID' => $arParams['ROW_ID']));
$row = $main_query->exec()->Fetch();
Object-relational mapping
Модификация данных
• Статические методы add(), update(), delete()
• Вызывают соответствующие события.
• Производят встроенную проверку полей сущностей,
вызывая метод checkFields().
• Возвращают объекты типов Bitrix\Main\Entity\AddResult,
UpdateResult и DeleteResult. Назначение этих объектов –
сообщить об успешности операции и дать доступ к
ошибкам.
Object-relational mapping
Проверка данных
• Метод checkFields() проверяет поля на обязательные
значения (атрибут поля сущности required) и соответствие
маске (атрибут format).
• Для дополнительных проверок класс сущности может
переопределить этот метод.
• В случае ошибки метод должен добавить ошибку в объект
результата. Ошибка может быть либо общая для всей
сущности, либо относиться к конкретному полю.
$result->addError(new Entity\EntityError("Нельзя изменить запись номер 1."));
$result->addError(new Entity\FieldError('NAME', 'Поле «имя» очень странное.'));
Object-relational mapping
События
• Датаменеджер при модификации данных отправляет
события.
• Названия событий строятся автоматически и имеют вид
<КодСущности> On( Before|<пусто>| After)( Add| Update|
Delete), например CultureOnBeforeDelete.
• Отменить операцию могут только обработчики событий
OnBefore.
OnBeforeUpdate(array("id"=>$primary, "fields"=>$data))
checkFields()
OnUpdate(array("id"=>$primary, "fields"=>$data))
update
OnAfterUpdate(array("id"=>$primary, "fields"=>$data))
Спасибо за внимание!
Вопросы?
Download