Удаление объекта Doctrine vs delete, сравнение производительности

17

При использовании доктрины я заметил, что для удаления объекта мне нужно получить этот объект по заданному параметру (имя, идентификатор и т. д.), а затем вызвать метод удаления. С другой стороны, в запросе я могу просто выполнить запрос на удаление.

Итак, похоже, что с использованием стиля ORM требуется две операции, а общая операция sql требует одной операции. Вот почему, я немного запутываюсь, следует ли нам использовать операцию удаления (или обновления) в ORM? Разве это не хуже в производительности? Или есть что-то еще, что мне не хватает? Можно ли это сделать другим способом в стиле ORM?

    
задан Rana 14.07.2012 в 21:15
источник

2 ответа

38

В Doctrine2 вы можете вызвать delete на прокси-объекте, который не загружен из базы данных. Просто создайте «фиктивный» объект, что-то вроде:

$user = $em->getPartialReference('model\User', array('id' => $id));
$em->remove($user);

Он не требует начального запроса, но я не совсем уверен, что Doctrine все еще делает это внутри fush . Я не вижу его в SqlLog.

Просто чтобы добавить, я думаю, что это ожидаемое поведение любого приличного ORM. Он касается объектов и отношений. Он должен знать, что перед удалением чего-то существует. ORM - это не просто генератор запросов . Как правило, собственный запрос всегда будет быстрее в любом ORM. Любая ORM добавляет слой абстракции, и для ее выполнения требуется некоторое время. Это типичный компромисс, вы получаете некоторые причудливые функции и чистый код, но немного теряете производительность.

EDIT:

Я рад, что это сработало для вас. Фактически я наткнулся на другую проблему, которая заставила меня понять, что прокси и частичные объекты на самом деле не то же самое. Частичные объекты представляют экземпляр реального класса модели и заполняют его необходимыми значениями. После инициализации частичного объекта lazy-load больше не работает на нем. Например, если вы делаете частичный объект только с идентификатором и хотите удалить только в том случае, если другое поле объекта удовлетворяет некоторому условию, оно не будет работать, потому что это другое поле всегда будет нулевым.

С другой стороны, прокси-серверы работают с ленивой загрузкой и не разделяют проблем, которые имеют частичные объекты. Поэтому я настоятельно рекомендую не использовать метод getPartialReference , вместо этого вы можете сделать что-то вроде:

$user = $em->getReference('model\User', $id);
$em->remove($user);

Метод getReference возвращает объект, если он уже загружен, или прокси-сервер, если это не так. Прокси-сервер может ленить все остальные значения, если / когда они вам понадобятся. Что касается вашего примера, они будут вести себя точно так же, но прокси-серверы, безусловно, лучший способ пойти.

    
ответ дан ZolaKt 14.07.2012 в 22:45
источник
  • Спасибо за информацию и разъяснение –  Rana 15.07.2012 в 08:23
4

Готово! для меня это сработало, как это добавить строку 3:

$user = $em->getReference('model\User', $id);
$em->remove($user);
$em->flush();
    
ответ дан Estefanio NS 02.12.2015 в 19:23
источник