我正在尝试实现并掌握我的MVC项目中的Data Mapper模式。我知道之前有人问过,但我仍然不确定我是否朝着正确的方向前进。我在下面粘贴了我的Controller,Datamapper和Domain Object / Entity代码:
用户登陆mywebsite.com/dashboard/index并从事件日志数据库表中查看事件列表。 index()函数创建一个Datamapper实例并传递数据库包装器。然后使用从Data mapper获取的数据动态生成HTML表。
class DashboardController extends BaseController {
public function index() {
require_once '../app/domain/mappers/EventMapper.php';
require_once '../app/include/HTMLTableCreator.php';
try {
$eventMapper = new EventMapper(new Database('db'));
$table = new HTMLTableCreator($eventMapper->findByLimit(20));
} catch (DatabaseException $e) {
}
$this->view('/home/dashboard', ['table' => $table->toString()]);
}
}
此类包含findByLimit()方法,用于从数据库中检索最后20个日志事件。 fetchCollection()方法填充域实体并在数组中收集这些实体以返回到控制器。
当SQL查询返回多行(=多个域对象)时,我应该创建一个由多个数据映射器使用的泛型集合函数吗?数据映射器可以使用任何类型的数据源吗?
require_once '../app/domain/entities/Event.php';
require_once '../app/domain/interfaces/EventMapperInterface.php';
/**
* EventMapper class
*/
class EventMapper implements EventMapperInterface {
protected $dbh;
protected $elements;
public function __construct(Database $dbh) {
$this->dbh = $dbh;
}
public function fetchCollection($objects) {
foreach($objects as $object) {
$event = new Event();
$event->setId($object['id']);
$event->setDateTime($object['datetime']);
$event->setMessage($object['message']);
$event->setHostname($object['hostname']);
$this->elements[] = $event;
}
return $this->elements;
}
public function findByLimit($limit = 20) {
$events = $this->dbh->sql_select('SELECT * FROM eventlog LIMIT ' . $limit, []);
return $this->fetchCollection($events);
}
}
最后,域对象包含一些简单的getter和setter。这是否可以对域对象的属性进行验证?
class Event {
protected $id;
protected $dateTime;
protected $message;
protected $hostname;
public function setId($id) {
$this->id = $id;
}
public function getId() {
return $this->id;
}
public function setDateTime($dateTime) {
$this->dateTime = $dateTime;
}
public function getDateTime() {
return $this->dateTime;
}
// rest omitted for clarity
}
我在实施中遗漏了什么?
答案 0 :(得分:0)
当SQL查询返回多行(=多个域对象)时,我应该创建一个通用集合函数供多个数据映射器使用吗?
没有。如果你的obects具有db = 1的1 = 1的属性,那么使用现有的方法;例如PDO取-CLASS。无论如何,每个实体都有一个映射器更清晰。如果它们非常通用,那么使用" super"映射器。
数据映射器可以使用任何类型的数据源吗?
假设DataSource
是某种集合 - 读写接口,那么肯定。您有__construct(Database $dbh)
,可由__construct(DataSource $ds)
替换。
其他说明:尝试将数据库和映射器服务注入控制器。