【发布时间】:2012-03-30 01:17:00
【问题描述】:
我正在为我公司购买的数据仓库编写网络报告扩展。数据仓库是数据模型中立的,并且具有存储表关系和字段的元层数据的表。这使我可以很容易地编写一个基本的 ORM 类,这正是我想要做的。一切正常,但是...
我的 ORM 类包含 PDO 实例、表的字段(用作白名单)和字段的元层信息。它还具有映射表关系(生成 FROM / JOIN 子句)和映射从 Web 提供的过滤器(生成 WHERE 子句)的便利功能。
SELECT 子句根据请求的模型在 ORM 的子类中生成。当页面加载时,需要构建几个模型。显然,我只需要一个 ORM 实例(如单态),但我希望每个子类都继承 ORM 的属性和便利功能——无需在每次实例化子类时重做父类的查询。
单例模式可能适合这里,但我发现很难对单例进行子类化。而且我似乎无法让静态属性正常工作。
我想我已经接近了,但我要么错过了一些东西,要么让这件事变得太难了。我现在正在考虑将属性放入一个薄类并从那里扩展,同时将便利功能与特征混合。我已经看到有关此主题的类似问题,但尚未提出明确的解决方案。
我不在工作,但这是一个简化的代码示例,应该可以为您提供我正在尝试做的事情的要点。
Class ORM {
protected $conn;
protected $fields;
protected $relations;
protected $table;
protected $sql;
public function __construct ($view, $database) {
$this->conn = new PDO(...$database...);
$this->table = $view;
$this->getFields();
$this->getRelations();
}
private function getFields () {
//select fields from metalayer where table = $table;
//$this->fields = $result;
}
private function getRelations () {
//select relations from relations where table = $table;
//$this->relations = $result;
}
protected function mapTables ($tables) {
// $this->sql = "FROM $this->table";
// foreach ($tables as $table) {
// $this->sql .= "LEFT JOIN $table ON $relations[$table]['key1'] = $relations[$table]['key2'];
}
protected function mapFilters ($filters) {
// $this->sql = "WHERE 1=1";
// foreach $filters as $filter {
// $this->sql .= "AND ($filter['field'] = $filter['criterion1'] OR ...criterion2, etc.)
}
}
Class ExampleModelDAO extends ORM {
public function __construct($view, $database, $params) {
parent::__construct($view, $database);
// parse params
parent::mapTables($tables);
parent::mapFilters($filters);
}
public function get() {
// Prepend $this->sql with SELECT statement specific to model
// Query database and return model
}
}
【问题讨论】:
-
您应该将 PDO 实例作为依赖项传入。这将使您在进行测试时更容易替换为模拟对象。