Что дает Doctrine ORM такого, чего нет у mysqli_fetch_object некоторого пользовательского кода?

#php #mysqli #orm #doctrine-orm

#php #mysqli #orm #doctrine-orm

Вопрос:

Удивлен, что я еще не вижу этого вопроса.

В чем разница между Doctrine ‘s getResult() и MySQLi's mysqli_fetch_object ?

Я использовал Doctrine из-за его способности преобразовывать строки таблицы в объекты. Но mysqli_fetch_object несколько строк кода могут сделать то же самое для меня и намного эффективнее.

Из того, что я вижу, Doctrine ORM — это библиотека, которая выполняет за вас большую работу и имеет некоторые преимущества. В чем заключаются все эти преимущества, я не уверен. Я использовал некоторые из них. Я начал использовать ORM, думая, что это потрясающе, и так оно и было, но понимая, насколько он тяжеловесен.

Я начал изучать mysqli и вижу, что там есть fetch_object . Ну что за привет? Что Doctrine делает лучше? Единственными преимуществами, которые я вижу, являются

  • независимость ядра базы данных
  • автоматическая упаковка-распаковка (строка таблицы <=> объект)
  • ассоциации и обновление базы данных SQL из ассоциаций
  • автоматическое экранирование при использовании persist()

Некоторые действительно классные преимущества:

  • автоматическое сохранение в базе данных любых изменений объекта, если он «управляемый»
  • кэширует запросы, поэтому, если вы обращаетесь к базе данных с одним и тем же SQL 1000 раз, он обращается к базе данных только один раз

все вышеперечисленное великолепно, но я не уверен, что они достаточно хороши, чтобы продолжать использовать ORM….

Для этого ответа я ищу то, что, возможно, пропустил. Зачем иметь такого монстра, как ORM, когда я могу объявить объект и mysqli_fetch_object выполнить работу по преобразованию?

Примечание: Я вижу ответы, в которых говорится, что mysqli_fetch_object есть единственный метод, который преобразует строку таблицы в объект для вас, а Doctrine ORM — это все. Я больше ищу ответ… что дает Doctrine ORM такого, чего не может дать mysqli_fetch_object.

Я подумываю о том, чтобы прекратить использование Doctrine и поискать любые причины, по которым я могу пожалеть об этом позже.

Код

Чтобы показать некоторый код

 /* 
 * Both return an object of class Product
 * 
 * one uses mysqli
 * one used ORM
 */
$r = new Repository();

//outputs product model using MySQLi
//0.130990 sec for 10 runs (XDEBUG   Qcachegrind)
var_dump($r->getProductInfo(1)->getModel());   

//outputs product model using ORM
//3.431963 sec for 10 runs (XDEBUG   Qcachegrind)
var_dump($r->getORMProductInfo(1)->getModel());

//if I run above in a loop some 1000  times, 
//ORM caches my query and hits DB only once
//while MySQLi has no caching set up
//hence ORM outperforms MySQLi when tests are run with multiple same queries
  

Репозиторий

 class Repository extends GenericRepository
{

    /* 
     * MySQLi with some custom code I wrote
     */
    function getProductInfo(int $productId)
    {
        $sql = "
            SELECT model FROM product WHERE id = ?
            ";
        $result = $this->getLink()->paramQuery($sql, $productId);
        return $result->getSingleObject(Product::class);
    }

    /*
     * Doctrine ORM
     */
    function getORMProductInfo(int $productId)
    {
        return $this->getEntityManager()->find(Product::class, 1);
    }
}
  

Результирующий класс MySQLi

 class MySqlResult
{

    /**
     * Get single object
     */
    function getSingleObject(string $className)
    {
        return $this->result->fetch_object($className);
    }
}
  

Продукт

 /**
 * Product
 *
 * @Table(name="product")
 *
 * @Entity
 */
class Product
{

    /**
     *
     * @var integer @Column(name="id", type="integer", nullable=false)
     *      @Id @GeneratedValue
     */
    private $id;

    /**
     *
     * @var string @Column(name="model", type="string", length=100, nullable=false)
     */
    private $model;
}
  

Комментарии:

1. Те 4 привилегии, которые вы упомянули, плюс тот факт, что fetch_object извлекается stdObject , а не фактический объект класса, на самом деле действительно ценны и делают использование ORM оправданным для большинства людей.

2. Спасибо. Хотя смотри MySqlResult::getSingleObject выше. Я могу указать и использовать свой собственный класс пользовательских объектов и извлекать данные непосредственно в этот объект. т.е. Product class object.

3. Некоторые другие преимущества, которые приходят мне на ум: преобразование типов ; Блокировка ; Прокси и отложенная / нетерпеливая загрузка ; События и обратные вызовы жизненного цикла . Но если вас устраивают простые объекты — делайте это проще.