5

假设我有两个模型:

class Book
{
    public $book_id;
    public $book_author_id;
    public $title;
}

class Author
{
    public $author_id;
    public $author_name;
}

我习惯写这样的东西:

$DB->query("SELECT book_id, title, author_name 
            FROM book 
            LEFT JOIN author 
                ON book_author_id = author_id
           ");

假设,我对对此关联进行单独查询不感兴趣。我该如何进行?以下是我听说过的一些事情:

  • 创建 JOIN 的 MySQL VIEW
  • 创建 VIEW 的模型类

我正在处理的应用程序涉及数十个表,并且在程序代码中进行了高度优化(例如,几乎没有 SELECT * 任何地方)。我正在重构以使其更易于维护(我也是最初的创建者),但我希望能够在需要时灵活地使用连接,而不会影响我的文件和数据库调用的结构。

我的一个可能相关的问题与包含其他模型有关:

class Author
{
    public $author_id;
    public $author_name;

    /* @var Book */ //<--don't really fully understand this but I've seen something like it somewhere
    public (array) $authors_books;
}

我仍在寻找答案,但如果您能以我的方式发送链接,将不胜感激。

4

3 回答 3

3

您所说的“模型”实际上是域对象。他们应该负责处理领域业务逻辑,与存储无关。

与存储相关的逻辑和交互应由单独的对象组处理。最明智的解决方案之一是使用数据映射器。每个映射器可以处理多个表和复杂的 SQL。

至于您的查询,此类查询的结果将包含适合传递给域对象集合的信息。

顺便说一句,该查询毫无用处。您忘记了每本书可以有多个作者。以这本书为例——它有 4 位不同的作者。要使此查询有用,您应该必须GROUP_CONCAT()基于author_idbook_id

实现此类JOIN语句时,数据库响应很可能是一个集合:

$mapper = $factory->buildMapper('BookCollection');
$collection = $factory->buildCollection('Book');

$collection->setSomeCondition('foobar');
$mapper->fetch( $collection );
foreach ( $collection as $item )
{
    $item->setSomething('marker');
}
$mapper->store( $collection );

PS您的代码示例似乎正在泄漏抽象。让其他结构直接访问对象的变量是一种不好的做法。

PPS看来您对 MVC 模型部分的理解与我的看法大不相同。

于 2012-07-16T21:54:05.810 回答
2

数据库连接是关系数据库的产物,您不需要对它们进行建模。您需要对您的数据什么以及它的行为方式进行建模,例如,您的实例中可能有一个getBooks()方法Author,或者您的类中有一个静态getByAuthor()方法Book(通常,$author->getBooks()应该实现为Book::getByAuthor($this),因此您的Author类不应该关心Book的实现细节)。自动实例化所有相关数据并不总是一个好主意(例如Book,通过给定实例实例化所有书籍的Author实例,正如您似乎正在考虑使用您的$author_books属性),因为这可能很容易降级为“将整个数据库加载到内存中每个请求”的场景。

于 2012-07-16T21:48:19.283 回答
1

如果您尝试在类中建模您的数据库,这是一个已经解决的问题。

我建议你试试Doctrine框架,它是 PHP 的完整 ORM 框架。

希望有帮助。

于 2012-07-16T21:11:12.360 回答