2017-01-21 3 views
0

Предположим, что у меня есть запрос, который возвращает следующие данные:ZF2/ZF3 гидрат объекта и вложенные объекты из одного запроса

RangeId | MinValue | MaxValue | Resolution | UnitId | UnitName 

Я хочу, чтобы увлажнять объект MeasurementRange с приведенными выше данными.

class MeasurementRange { 
    public function getRangeId() {...}; 
    public function setRangeId($id) {...}; 
    public function getRange() {...}; 
    public function setRange(Range $range) {...}; 
    public function getUnit() {...}; 
    public function setUnit(Unit $unit) {...}; 
} 

class Range { 
    public function getMinValue() {...}; 
    public function setMinValue(float $minVal) {...}; 
    public function getMaxValue() {...}; 
    public function setMaxValue(float $maxVal) {...}; 
    public function getResolution {...}; 
    public function setResolution(float $resolution) {...}; 
} 

class Unit { 
    public function getUnitId() {...}; 
    public function setUnitId(int $id) {...}; 
    public function getUnitName() {...}; 
    public function setUnitName(string $name) {...}; 
} 

Как вы можете видеть объект MeasurementRange установил Range и Unit объектов.

Как я могу увлажнять MeasurementRange и внутренние Range и Unit объектов по вышеуказанному запросу?

PS: Я не указал защищенные свойства объектов. Наверное, они само собой разумеются.

+1

Может быть, вы должны смотреть на [Учение ORM] (Http: //docs.doctrine -project.org/projects/doctrine-orm/en/latest/)? Это может быть полезно для вас. – Wilt

+0

@Wilt, спасибо за предложение. я боюсь, что изучение нового инструмента потребует времени, и я довольно ограниченный для этого проекта. у вас есть идея, как делать то, что я хочу, с помощью родных zf2 вещей? –

+0

@ Успокойся, исправьте меня, если я ошибаюсь, но из моего быстрого взгляда на Doctrine ORM, я не уверен, что это будет отображать этот объект. это очень хорошо, когда у вас есть таблицы, соответствующие вашим классам сущностей, но это не то, что у меня есть. –

ответ

1

Вам нужно создать картограф, который будет использовать ваш dbAdapter для выборки данных в виде массива, а затем использовать увлажняющий гидрат всех объектов, и, наконец, добавить Range и Unit к MeasurementRange. Вы также можете создать собственный гидрант (это будет еще лучше, с точки зрения единой ответственности).

у меня нет времени, чтобы очистить пример ниже, но это то, что она может выглядеть :)

final class LanguageMapper 
{ 
    /** 
    * @param LanguageTable $languageTable 
    * @param PackageTable $packageTable 
    * @param Cache   $cache 
    * @param LoggerInterface $logger 
    */ 
    public function __construct(LanguageTable $languageTable, PackageTable $packageTable, Cache $cache, LoggerInterface $logger) 
    { 
     $this->languageTable = $languageTable; 
     $this->packageTable = $packageTable; 
     $this->cache = $cache; 
     $this->logger = $logger; 
    } 

    /** 
    * @param array $where 
    * 
    * @return array List of active languages 
    */ 
    public function findActive(array $where = []) 
    { 
     try { 
      if (empty($where) && $this->cache->hasItem('active_languages')) { 
       return unserialize($this->cache->getItem('active_languages')); 
      } 
     } catch (RuntimeException $exception) { 
      $this->logger->critical($exception->getMessage(), [ 
       'exception' => $exception, 
       'file' => $exception->getFile(), 
       'line' => $exception->getLine(), 
      ]); 
     } 
     /* @var $adapter \Zend\Db\Adapter\Adapter */ 
     $adapter = $this->languageTable->getGateway()->getAdapter(); 
     $sql = new Sql($adapter); 
     $select = $sql->select()->columns([Select::SQL_STAR]) 
      ->from('language') 
      ->join('package', 'package.id = language.package', Select::SQL_STAR, Select::JOIN_LEFT) 
      ->where(array_merge($where, ['active' => true])) 
      ->order(['position']); 
     $selectString = $sql->buildSqlString($select); 

     $resultSet = $adapter->query($selectString, Adapter::QUERY_MODE_EXECUTE); 
     $languages = []; 
     $hydrator = new ArraySerializable(); 
     foreach ($resultSet as $result) { 
      $language = new Language(); 
      $package = new Package(); 
      $hydrator->hydrate((array) $result, $package); 
      $hydrator->hydrate((array) $result, $language); 
      $language->setPackage($package); 
      $languages[] = $language; 
     } 
     if (empty($where)) { 
      try { 
       $this->cache->setItem('active_languages', serialize($languages)); 
      } catch (RuntimeException $exception) { 
       $this->logger->warning($exception->getMessage(), [ 
        'exception' => $exception, 
        'file' => $exception->getFile(), 
        'line' => $exception->getLine(), 
       ]); 
      } 
     } 

     return $languages; 
    } 
} 
+0

Я тоже думал о тех же идеях. проблема в том, что у вас много объектов (что у меня есть). когда ваш картограф получает данные, а затем увлажняет, а затем собирает объект - слишком много предвидений, которые могут повлиять на производительность системы. написание специального гидратора и использование AggregateHydrator для сборки гидраторов приводит к тому, что многие гидраторы и гидраторы становятся очень зависимыми от вашего запроса: как только вы что-то изменяете в запросе, вам нужно сменить гидратор. так как всегда плюсы и минусы ... я ответил на ваш ответ и посмотрю, что должны написать другие ребята. –

Смежные вопросы