5

2 つのモデルがあるとします。

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 * はほとんどありません)。より保守しやすいようにリファクタリングしています (私も元の作成者です) が、ファイルの構造や DB 呼び出しを損なうことなく、必要に応じて結合を使用できる柔軟性を持ちたいと考えています。

おそらく関連する質問は、他のモデルを含めることに関連しています。

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

あなたが「モデル」と呼んでいるものは、実際にはドメイン オブジェクトです。ドメイン ビジネス ロジックの処理を担当する必要があり、ストレージとは関係ありません。

ストレージ関連のロジックと相互作用は、オブジェクトの別のグループで処理する必要があります。最も賢明な解決策の 1 つは、データ マッパーを使用することです。各マッパーは、複数のテーブルと複雑な 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

DB をクラスでモデル化しようとしている場合、これは既に解決された問題です。

PHP 用の完全な ORM フレームワークであるDoctrineフレームワークを試してみることをお勧めします。

それが役立つことを願っています。

于 2012-07-16T21:11:12.360 に答える