#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. Некоторые другие преимущества, которые приходят мне на ум: преобразование типов ; Блокировка ; Прокси и отложенная / нетерпеливая загрузка ; События и обратные вызовы жизненного цикла . Но если вас устраивают простые объекты — делайте это проще.