我正在http://framework.zend.com/manual/2.0/en/user-guide/database-and-models.html上关注该教程,并且我已经设置了Module::getServiceConfig()
和我的AlbumTable
课程。
现在说我需要执行存储过程来获取结果集...而不是标准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());
}
问题在于,$result
返回的是ArrayObject
的集合...而不是Album
模型的集合。那么如何执行存储过程但仍能根据我在Module::getServiceConfig()
中设置的内容得到结果?
请不要问我的存储过程在做什么......这与这个问题无关。点是,它返回与Album
模型兼容的结果。
^并不意味着态度,只是试图拯救每个人建议我不需要使用存储过程。
答案 0 :(得分: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;
}
}
<强>更新强>
我并没有真正理解ReflectionHydrator
发生的事情。它通过反射填充我的对象,并没有调用我的exchangeArray()
方法。当我在smalldatetime
方法中将数据库中的\DateTime
值转换为exchangeArray()
对象时,我意识到这一点......它没有被调用。
对此的解决方法是使用ArraySerializable
保湿器。所以我已经更新了上面的代码来证明这一点。
如果您希望保湿器使用您的孵化器(例如setArtist()
和setTitle()
),您可以使用ClassMethods
保湿器。
如果您的属性是公开的(或者您正在使用魔法__set()
方法),则可以使用ObjectProperty
水分器,它只会将值分配给您的属性。