2013-08-21 41 views
1

我正在按照http://framework.zend.com/manual/2.0/en/user-guide/database-and-models.html的教程進行操作,並且已經設置了我的Module::getServiceConfig()和我的AlbumTable類,如他們所示。如何在ZF2中執行手動編寫的查詢或存儲過程

現在說我需要執行一個存儲過程來獲得我的結果集...不是標準的SELECT。我仍然希望結果集是Album模型的集合。如何才能做到這一點?

這裏是什麼,我已經試過一個例子:

AlbumTable.php:

public function findByArtist($artist) { 
    $adapter = $this->tableGateway->getAdapter(); 
    $result = $adapter->query(
     "EXEC spGetAlbums @artist = :artist", 
     array(':artist' => $artist) 
    ); 

    var_dump($result->current()); 
} 

的問題,這是返回的$resultArrayObject個集...不Album模型的集合。那麼如何執行存儲過程,但仍然可以根據我在Module::getServiceConfig()中設置的結果來獲得結果?

請不要打擾詢問我的存儲過程正在做什麼......這與此問題無關。點是,它返回與Album模型兼容的結果。
^不是態度,只是試圖挽救每個人建議我不需要使用存儲過程的時間。

+0

您需要手動將ArrayObjects合併到相冊對象中。因爲在那裏你正在做一個本地的SQL查詢,所以沒有其他的魔法發生;) – Sam

+0

有沒有辦法在'TableGateway'對象上執行本機SQL查詢? – Travesty3

回答

3

由於@Sam在問題評論中提出,似乎沒有辦法在TableGateway對象上執行原生SQL查詢,因此您必須手動提供數據對象。

HydratingResultSet看Zend的文件後,這裏就是我想出了一個解決方案:

namespace Album\Table; 

use Zend\Db\TableGateway\TableGateway; 
use Zend\Db\ResultSet\HydratingResultSet; 
use Zend\Stdlib\Hydrator; 

class Album { 

    protected $tableGateway; 

    public function __construct(TableGateway $tableGateway) { 
     $this->tableGateway = $tableGateway; 
    } 

    public function findByArtist($artist) { 
     $adapter = $this->tableGateway->getAdapter(); 
     $result = $adapter->query(
      "EXEC spGetAlbums @artist = :artist", 
      array(':artist' => $artist) 
     ); 

     $dataSource = $result->getDataSource(); 
     if ($dataSource instanceof \Iterator) { 
      $result = new HydratingResultSet(
       new Hydrator\ArraySerializable(), 
       new \Album\Model\Album() 
      ); 
      $result->initialize($dataSource); 
     } 

     return $result; 
    } 
} 

UPDATE:

我並沒有真正得到了什麼事情與ReflectionHydrator。它通過反射填充我的對象,並沒有調用我的方法exchangeArray()。我意識到這一點時,我去在數據庫中將smalldatetime值轉換爲方法中的\DateTime對象......它沒有被調用。

解決方法是使用ArraySerializable hydrator代替。所以我更新了上面的代碼來證明這一點。

如果您想讓水化器使用您的吸附器(如setArtist()setTitle()),您可以使用ClassMethods水化器。

如果你的屬性是公共的(或者,如果您使用的是魔法__set()方法),你可以使用ObjectProperty水化和它只是將值賦給你的屬性。

+0

好的答案;)「HydratingResultSet」的第一個參數可以改爲其他可能的Hydrators,比如'ClassMethodsHydrator'或者你自己的hydrator – Sam

+0

@Sam:花了我一段時間才意識到水化器​​之間的差異,但是我終於弄明白了並用更多信息更新了我的答案,希望對其他人有所幫助。 – Travesty3

相關問題