1

我正在学习http://framework.zend.com/manual/2.0/en/user-guide/database-and-models.html上的教程,并且我已经按照他们的说明设置了我Module::getServiceConfig()和我的班级。AlbumTable

现在说我需要执行一个存储过程来获取我的结果集......不是标准的SELECT。我仍然希望结果集是Album模型的集合。如何才能做到这一点?

这是我尝试过的示例:

专辑表.php:

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

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

问题在于$result返回的是ArrayObjects 的集合......而不是Album模型的集合。那么如何执行存储过程但仍然根据我设置的内容获得结果Module::getServiceConfig()

请不要问我的存储过程在做什么......这与这个问题无关。Album关键是,它返回与模型兼容的结果。
^ 不代表态度,只是想节省大家建议我不需要使用存储过程的时间。

4

1 回答 1

3

正如@Sam 在问题评论中所建议的那样,似乎没有办法对TableGateway对象执行本机 SQL 查询,因此您必须手动水合数据对象。

在查看 Zend's Docs on 之后HydratingResultSet,这是我想出的解决方案:

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;
    }
}

更新:

我并没有真正了解ReflectionHydrator. 它通过反射填充我的对象,并且没有调用我的exchangeArray()方法。smalldatetime当我在我的方法中将数据库中的值转换为\DateTime对象时,我意识到了这一点exchangeArray()……它没有被调用。

解决此问题的方法是改用ArraySerializable保湿剂。所以我更新了上面的代码来证明这一点。

如果您希望 hydrator 使用您的 setter(如setArtist()setTitle()),您可以使用ClassMethodshydrator。

如果您的属性是公开的(或者如果您使用的是魔法__set()方法),您可以使用ObjectPropertyhydrator,它只会将值分配给您的属性。

于 2013-08-21T17:55:30.503 回答