연결에 저장된 메타 데이터에 액세스 할 내가 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 구조에서 결과 쿼리 :
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
메타 데이터 열에 어떻게 액세스합니까?
메타 데이터 열에 액세스 할 수있는 유일한 방법은 명시적인 innerJoin
을 LinkingAuthorBook
(연결된 book_link 별칭 포함)에 추가하는 것이었지만 이로 인해 결과 SQL에 또 다른 조인이 발생했습니다. 원본 쿼리에서 필요한 데이터에 액세스 할 수 있으므로 이해가되지 않습니다.
- 업데이트 (2012년 3월 7일) - 루프, 나는로부터 메타 데이터를 결합 할 수 없습니다 저자에 속하는를 통해 모든 책을 반복 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);
예 루프 -> 도서 :
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 객체를 수동으로 수화시키는 것이 다른 쿼리를 발행 할 필요없이 메타 데이터에 접근 할 수있는 유일한 방법이다.
롤 (Lol)은 이미 Google에서 검색했습니다. 순환 참조 ftw. –