Определение того, какое поле заставляет Doctrine повторно запрашивать базу данных
Я использую доктрину с Symfony в нескольких проектах веб-приложений.
Я оптимизировал многие запросы в этих проектах, чтобы выбрать только необходимые поля из базы данных. Но со временем были добавлены новые функции и - в нескольких случаях - в коде используются дополнительные поля, что заставляет ленивый загрузчик Doctrine повторно запрашивать базу данных и увеличивает количество запросов на некоторых страницах с 3 до 100+
Поэтому мне нужно обновить исходный запрос, чтобы включить все обязательные поля. Однако, по-видимому, для Доктрины не существует простого способа регистрации того, какое поле вызывает выдачу дополнительного запроса, поэтому становится кропотливой работой просеивать код в поисках использования полей, которых нет в исходном запросе.
Есть ли способ зарегистрировать доктрину, когда получатель обращается к полю, которое не было увлажнено?
2 answers
У меня не было этой проблемы, но я просто посмотрел на класс Doctrine_Record. Вы пробовали добавить некоторые отладочные выходные данные в метод _get()? Я думаю, что в этой части вам следует искать решение:
if (array_key_exists($fieldName, $this->_data)) {
// check if the value is the Doctrine_Null object located in self::$_null)
if ($this->_data[$fieldName] === self::$_null && $load) {
$this->load();
}
Просто включите ведение журнала SQL, и вы сможете определить виновного по именам псевдонимов. О том, как это сделать в Доктрине 1.2, см. Этот пост .
В основном: создайте класс, который расширяет Doctrine_EventListener:
class QueryDebuggerListener extends Doctrine_EventListener
{
protected $queries;
public function preStmtExecute(Doctrine_Event $event)
{
$query = $event->getQuery();
$params = $event->getParams();
//the below makes some naive assumptions about the queries being logged
while (sizeof($params) > 0) {
$param = array_shift($params);
if (!is_numeric($param)) {
$param = sprintf("'%s'", $param);
}
$query = substr_replace($query, $param, strpos($query, '?'), 1);
}
$this->queries[] = $query;
}
public function getQueries()
{
return $this->queries;
}
}
И добавьте прослушиватель событий:
$c = Doctrine_Manager::connection($conn);
$queryDbg = new QueryDebuggerListener();
$c->addListener($queryDbg);