Zend数据映射器设计
我正在使用Zend Framework,并遵循将数据层从域层分离出来的设计模式,在实现Data映射器的方法时引发问题,所以我实现了save()
,它根据域模型是否包含id属性来插入和更新和find()
哪些返回记录域对象基于id参数,但如果我需要
我应该直接使用继承了Zend_Db_Table_Abstract的类来满足这些需求,还是应该为每个需求实现方法?
我对如何划分符合我需求和未来需求的Data Mapper的功能有点困惑
您可以添加单个查找器方法,例如
class PersonMapper
{
… // other code
public function findByLastName()
{
// … fetch rowset and map them
}
public function countByLastName()
{
…
但是,当您需要查询多个列或想要通过任意标准处理CRUD时,这会很快失去控制。 你不需要类似的方法
public function findByLastNameAndBirthdayAndMaritalStatus()
简单的解决方案是使用Zend_Db_Table_Select
创建查询,然后将这些查询传递给Data Mapper以执行并映射它们,例如在DataMapper中
public function getSelect()
{
return $this->personTable->select();
}
public function findBy(Zend_Db_Table_Select $select)
{
$people = $this->personTable->fetchAll($select);
// map people to People objects
}
你可以用Mapper返回并接受PersonQueryBuilder来进一步抽象它,它隐藏了内部的SQL语义,而让你指定你的域对象。 尽管如此,这是更多的努力
另请参阅存储库和规范模式。
尽管Gordon很可能有正确的答案,但我发现目前我的口味和需求过于复杂。
我为我的所有域映射器使用了基本映射器类,并且尽可能多地将基本类功能放到了基类中。
我使用了按列查找方法,在我的所有映射器中工作得很好:
//from abstract class Model_Mapper_Abstract
//The constructor of my base class accepts either a dbtable model
// or the name of a table stored in the concrete mapper tablename property.
public function __construct(Zend_Db_Table_Abstract $tableGateway = null)
{
if (is_null($tableGateway)) {
$this->tableGateway = new Zend_Db_Table($this->tableName);
} else {
$this->tableGateway = $tableGateway;
}
}
/**
* findByColumn() returns an array of entity objects
* filtered by column name and column value.
* Optional orderBy value.
*
* @param string $column
* @param string $value
* @param string $order optional
* @return array of entity objects
*/
public function findByColumn($column, $value, $order = null)
{
//create select object
$select = $this->getGateway()->select();
$select->where("$column = ?", $value);
//handle order option
if (!is_null($order)) {
$select->order($order);
}
//get result set from DB
$result = $this->getGateway()->fetchAll($select);
//turn DB result into domain objects (entity objects)
$entities = array();
foreach ($result as $row) {
//create entity, handled by concrete mapper classes
$entity = $this->createEntity($row);
//assign this entity to identity map for reuse if needed
$this->setMap($row->id, $entity);
$entities[] = $entity;
}
//return an array of entity objects
return $entities;
}
我希望你至少觉得这个作为一个创意发生器很有用。 此外,如果您希望在类似于此的方法中实现SQL Count()
语句,则在构建select()时使用Zend_Db_Expr()会更容易。