をリンクに保存されているアクセスメタデータは、私は3つのテーブルがあります。LinkingAuthorBookテーブルを使用して著者とブック間のM:Doctrine docs経由でノートパー教義テーブル
# schema.yml
Author:
connection: store-rw-library
tableName: lib_author
actAs: { Timestampable: ~ }
columns:
id:
type: integer(4)
unsigned: 1
primary: true
autoincrement: true
name:
type: string(50)
notnull: true
Book:
connection: store-rw-library
tableName: lib_book
actAs: { Timestampable: ~ }
columns:
id:
type: integer(4)
unsigned: 1
primary: true
autoincrement: true
name:
type: string(50)
notnull: true
relations:
Author:
class: Author
foreignAlias: Books
refClass: LinkingAuthorBook
LinkingAuthorBook:
connection: store-rw-library
tableName: lib_linking_author_book
columns:
author_id:
type: integer(4)
unsigned: 1
primary: true
book_id:
type: integer(4)
unsigned: 1
primary: true
created_at:
type: timestamp(25)
notnull: true
relations:
Author:
foreignAlias: AuthorBooks
Book:
foreignAlias: AuthorBooks
を、私はMとしての関係を確立しました。
class AuthorTable
{
public function getAuthor($id)
{
$q = Doctrine_Query::create()
->select('a.id AS author_id')
->addSelect('a.name AS author_name')
->addSelect('b.AuthorBooks')
->from('Author a')
->innerJoin('a.Books b')
->where('a.id = ?', $id);
$result = $q->fetchArray();
}
}
上記DQL構築物から結果のクエリ:
今、私は、1つのクエリで、特定の著者が執筆すべての書籍を取得するような何かをしようとしています
SELECT
m.id AS m__id,
m.name AS m__1,
m2.id AS m2__id,
m2.name AS m2__1,
m.id AS m__0,
m.name AS m__1
FROM
lib_author m
INNER JOIN
lib_linking_author_book m3 ON (m.id = m3.author_id)
INNER JOIN
lib_book m2 ON m2.id = m3.book_id
WHERE
(m.id = '163')
上記のクエリから、正しく結合を行っていることがわかりますが、schema.ymlファイルに設定されているLinkingAuthorBook.created_at
メタデータ列にはどのようにアクセスすればよいですか?
メタデータの列にアクセスできる唯一の方法は、LinkingAuthorBook
に関連付けられたbook_linkエイリアスを明示的にinnerJoin
に追加することでしたが、結果としてSQLに別の結合が生じました。元のクエリから必要なデータにアクセスできるため意味がありません。
- アップデート(2012年7月3日) - Iセットアップの作者に属しているすべての書籍を反復するループは、私はからのメタデータを組み合わせることができない場合
まだ問題が、発生していますLinkingAuthorBookテーブルまたはBookテーブルに別のクエリを強制しないでください。
更新クエリ:LinkingAuthorBookから
$q = Doctrine_Query::create()
->from('Author a')
->innerJoin('a.Books b')
->innerJoin('b.LinkingAuthorBook ab ON a.id = ab.author_id AND b.id = ab.book_id')
->where('a.id = ?', $id);
例ループ - >ブック:ブックの次のforループ
foreach ($author->getLinkingAuthorBook() as $link) {
// Works fine, no extra query
var_dump($link->getCreatedAt());
// Forces an extra query, even though 'name' is the column name
// So even though doctrine uses lazy-load, it should be able to
// get this data from the original query
var_dump($link->getBook()->getName());
}
と同じ - > LinkingAuthorBook:
foreach ($author->getBook() as $book) {
// Forces extra query
var_dump($book->getLinkingAuthorBook()->getCreatedAt());
// No extra query
var_dump($book->getName());
}
マイ回避策:
class Book
{
public $meta;
}
class AuthorTable
{
public function getAuthor($id)
{
$q = Doctrine_Query::create()
->from('Author a')
->innerJoin('a.Books b')
->innerJoin('b.LinkingAuthorBook ab ON a.id = ab.author_id AND b.id = ab.book_id')
->where('a.id = ?', $id);
$author = $q->fetchOne();
// Manually hydrate Book Meta
foreach ($author->getLinkingAuthorBook() as $authorBook) {
$authorBooks[$authorBook->getId()] = $authorBook;
}
foreach ($author->getBook() as $book) {
$book->meta = $authorBooks[$book->getId()];
}
}
}
だから今、私は余分なクエリを強制することなく、メタで、書籍を反復処理することができます。
foreach ($author->getBook() as $book) {
// No extra query
var_dump($book->meta->getCreatedAt());
// No extra query
var_dump($book->getName());
}
- アップデート(2012年3月8日) -
だから私はことができました次のコードでそれを証明するために:
foreach ($author->getBooks() as $book)
{
echo $book->getName().'- '.$book->LinkingAuthorBook[0]->getCreatedAt().'<br/>';
}
各反復は、新しいクエリがcreatedAt
値を取得するために発行される原因となりました。私は、MySQLで次のコマンドを発行してこれをしなかった:
mysql> set global log_output = 'FILE';
mysql> set global general_log = 'ON';
mysql> set global general_log_file = '/var/log/mysql/queries.log';
は、その後、私は/var/log/mysql/queries.log
を尾行し、生成された追加のクエリーを見ることができました。したがって、最初のクエリの後でBook :: Metaオブジェクトを手作業で水分補給することは、別のクエリを発行することなくメタデータにアクセスする唯一の方法です。
笑、これはすでにGoogleの検索を行った。循環参照ftw。 –