具有相同结果的 Doctrine 2 createQueryBuilder
Doctrine 2 createQueryBuilder with same result
我有 2 个不同的 QueryBuilder,return 结果相同。第一个 QueryBuilder return 是正确的结果。第二个 QueryBuilder return 是第一个的结果。
问题:如何强制第二个 QueryBuilder 从数据库而不是内存中获取数据?
用法:
/** @var SectionEntity $section */
foreach ( $subject->getSections() as $section ) {
/** @var QuestionEntity $question */
foreach ( $section->getQuestions() as $question ) {
// ...
}
}
这就是我调用 QueryBuilder 的方式:
/** @var SubjectEntity $subject */
$subject = $this->retrieveDefaultProfileQuestions();
/** @var SubjectEntity $old_subject */
$old_subject = $this->retrieveProfileQuestionsForUser( $user );
函数:
/**
* Retrieves default profile questions from database
*
* @return null|SubjectEntity
* @throws \Doctrine\ORM\NonUniqueResultException
*/
private function retrieveDefaultProfileQuestions() {
$queryBuilder = $this->createQueryBuilder( 's' );
$query = $queryBuilder
->select( 's, sc, q' )
->leftJoin( 's.sections', 'sc' )
->leftJoin( 'sc.questions', 'q', 'WITH', 'q.user IS NULL' )
->where( 's.type = :TYPE' )
->setParameter( 'TYPE', 'profile' )
->getQuery();
return $query->getOneOrNullResult();
}
/**
* Retrieves user's profile questions from database
*
* @param UserEntity $user
*
* @return null|SubjectEntity
* @throws \Doctrine\ORM\NonUniqueResultException
*/
private function retrieveProfileQuestionsForUser( $user ) {
$queryBuilder = $this->createQueryBuilder( 's' );
$query = $queryBuilder
->select( 's, sc, q' )
->leftJoin( 's.sections', 'sc' )
->leftJoin( 'sc.questions', 'q', 'WITH', 'q.user = :USER' )
->where( 's.type = :TYPE' )
->setParameter( 'USER', $user )
->setParameter( 'TYPE', 'profile' )
->getQuery();
return $query->getOneOrNullResult();
}
问题可能来自您发送给 mysql 的查询,它可能与之前的查询相同,因此在这种情况下 mysql 不会构建新的 execution plan
并且将从记忆中得到结果,我建议您尝试的一件事是将 ->select( 's, sc, q' )
更改为 ->select( 's.*, sc.*, q.*' )
我有 2 个不同的 QueryBuilder,return 结果相同。第一个 QueryBuilder return 是正确的结果。第二个 QueryBuilder return 是第一个的结果。
问题:如何强制第二个 QueryBuilder 从数据库而不是内存中获取数据?
用法:
/** @var SectionEntity $section */
foreach ( $subject->getSections() as $section ) {
/** @var QuestionEntity $question */
foreach ( $section->getQuestions() as $question ) {
// ...
}
}
这就是我调用 QueryBuilder 的方式:
/** @var SubjectEntity $subject */
$subject = $this->retrieveDefaultProfileQuestions();
/** @var SubjectEntity $old_subject */
$old_subject = $this->retrieveProfileQuestionsForUser( $user );
函数:
/**
* Retrieves default profile questions from database
*
* @return null|SubjectEntity
* @throws \Doctrine\ORM\NonUniqueResultException
*/
private function retrieveDefaultProfileQuestions() {
$queryBuilder = $this->createQueryBuilder( 's' );
$query = $queryBuilder
->select( 's, sc, q' )
->leftJoin( 's.sections', 'sc' )
->leftJoin( 'sc.questions', 'q', 'WITH', 'q.user IS NULL' )
->where( 's.type = :TYPE' )
->setParameter( 'TYPE', 'profile' )
->getQuery();
return $query->getOneOrNullResult();
}
/**
* Retrieves user's profile questions from database
*
* @param UserEntity $user
*
* @return null|SubjectEntity
* @throws \Doctrine\ORM\NonUniqueResultException
*/
private function retrieveProfileQuestionsForUser( $user ) {
$queryBuilder = $this->createQueryBuilder( 's' );
$query = $queryBuilder
->select( 's, sc, q' )
->leftJoin( 's.sections', 'sc' )
->leftJoin( 'sc.questions', 'q', 'WITH', 'q.user = :USER' )
->where( 's.type = :TYPE' )
->setParameter( 'USER', $user )
->setParameter( 'TYPE', 'profile' )
->getQuery();
return $query->getOneOrNullResult();
}
问题可能来自您发送给 mysql 的查询,它可能与之前的查询相同,因此在这种情况下 mysql 不会构建新的 execution plan
并且将从记忆中得到结果,我建议您尝试的一件事是将 ->select( 's, sc, q' )
更改为 ->select( 's.*, sc.*, q.*' )