> php教程 > PHP开发 > 본문

Yii2 ActiveRecord 다중 테이블 연관 및 다중 테이블 연관 검색 구현

高洛峰
풀어 주다: 2016-12-23 16:52:30
원래의
1332명이 탐색했습니다.

Yii의 ActiveRecord는 MVC의 M(모델 레이어), ORM의 O(객체)인 데이터베이스를 다루는 클래스입니다.

자주 묻는 질문입니다. 최근 그룹 내 피드백을 통해 아직도 이 문제를 이해하지 못하는 분들이 많다는 것을 느꼈습니다. 오늘은 이 문제를 명확하게 설명했습니다. yii2 ActiveRecord의 다중 테이블 연결과 이 연결을 최적화하는 방법을 살펴보겠습니다.

시나리오 요구 사항:

사용자 테이블 user와 사용자 채널 테이블 auth가 있다고 가정합니다. 두 데이터 테이블은 user.id와 auth.uid를 통해 일대일로 관련되어 있습니다. 이제 사용자 목록에 auth 테이블의 소스 채널 소스를 표시해야 하며 해당 채널은 검색 가능해야 합니다.

먼저 gii를 통해 사용자 및 인증 시리즈 관련 모델과 작업을 생성합니다. 여기서 자세한 설명은 제공되지 않습니다. xxx

를 참조하세요. 중요한 단계를 계속 살펴볼 것입니다.

1. 해당 AR 모델 클래스를 찾습니다. 사용자 테이블에

/**
* 关联auth表
*/
public function getAuth()
{
// hasOne要求返回两个参数 第一个参数是关联表的类名 第二个参数是两张表的关联关系
// 这里uid是auth表关联id, 关联user表的uid id是当前模型的主键id
return $this->hasOne(common\models\Auth::className(), ['uid' => 'id']);
}
로그인 후 복사

이 유형의 파일에 연결하십시오.

설정한 후에는 두 데이터가 테이블이 자동으로 연결됩니다! 사용자 목록 페이지를 방문합니다(목록 페이지는 gii에 의해 생성되었으며 지금까지 운영하지 않았습니다). 디버그를 통해 데이터베이스 쿼리를 보면 실제 쿼리가 auth 테이블과 연결되어 있지 않음을 찾는 것이 어렵지 않습니다. 🎜>

2. 그리드뷰에서 소스 채널 필드 source

<?= GridView::widget([
// other codes
&#39;columns&#39; => [
// other columns
&#39;auth.source&#39;,
]
]); ?>
로그인 후 복사
를 연관 테이블에 추가합니다.source?

걱정하지 마세요. 이제 실제 쿼리를 보기 위해 디버그를 엽니다.

uid = xxx;인 `auth`에서 *를 선택하는 것과 같은 많은 작업이 있음을 알 수 있습니다. 페이징이 기본적으로 20개의 데이터로 설정되어 있으면 유사한 쿼리가 20개 있습니다.

먼저 무슨 일이 일어났는지 알아볼까요?

사실 이게 php에 대한 기본지식이에요. 객체의 존재하지 않는 멤버 변수를 읽거나 쓸 때 __get() __set() 매직 함수가 자동으로 호출됩니다. Yii도 이를 활용하여 구현했습니다!

이 작업은 대부분의 사람들이 관련 테이블 데이터를 얻기 위해 그리드뷰에 메서드를 캡슐화하는 것과 거의 동일하지만! 20개의 SQL 쿼리는 분명히 많은 오버헤드를 증가시킵니다. 이것이 왼쪽 조인 작업이라면 좋을 것입니다!

3. SQL 최적화

최적화해야 할 사항은 다음과 같습니다.

20개의 SQL을 1개의 SQL로 변경

관련 테이블에 필요한 필드만 가져옵니다.

몇몇 학생들이 Yii와 함께 제공되는 작업을 최적화하는 방법이 무엇인지 소리치고 있습니다. 데이터 소스 획득으로 돌아가서 userSearch 모델의 검색 방법을 통해 사용자 목록의 데이터가 제공되는 것을 확인했습니다.

즉, 우리 데이터 쿼리는 실제로 관련 테이블 쿼리를 수행하지 않습니다! 이 경우 UserSearch

에 관련 검색어

$query = User::find();
$query->joinWith([&#39;auth&#39;]);
$query->select("user.*, auth.source");
로그인 후 복사
를 추가합니다. 사용자 목록 페이지를 다시 새로고침한 후 디버그 분석을 통해 두 개의 SQL이 우리의 관심을 끌었습니다

SELECT `user`.*, `auth`.`source` FROM `user` LEFT JOIN `auth` ON `user`.`id` = `auth`.`uid` LIMIT 20
SELECT * FROM `auth` WHERE `user_id` IN (20个uid);
로그인 후 복사
즉, 디버그 분석을 통해 쿼리 시간을 발견했습니다. DB가 많이 줄어들었습니다.

4. 관련 테이블 필드에 쿼리 추가

그리드뷰의 검색 모델도 검색 가능한 필드와 검색 불가능한 필드를 제어하는 ​​searchModel을 통해 구현됩니다.

이제 연관 테이블의 소스를 검색 가능하게 만들어야 하므로 searchModel에 속성 소스를 정의하고 이를 규칙에 추가합니다

public $source;
public function rules()
{
return [
// other rules
[&#39;source&#39;, &#39;safe&#39;],
];
}
로그인 후 복사
그런 다음 Gridview에서 auth.source를 수정합니다

// &#39;auth.source&#39;,
[
&#39;attribute&#39; => &#39;source&#39;,
&#39;value&#39; => &#39;auth.source&#39;,
&#39;label&#39; => &#39;渠道来源&#39;,
],
로그인 후 복사
이 시점에서 인터페이스는 괜찮지만 여전히 구현해야 합니다. 프로그램에서 검색하면 데이터 소스를 얻는 새로운 소스 조건을 추가할 수 있습니다.

$query->andFilterWhere([
// other params
&#39;auth.source&#39; => $this->source,
]);
로그인 후 복사
ActiveRecord의 몇 가지 사용법을 추가하겠습니다. Yii.

1, 객체를 배열로

$model = new ActiveRecord();

$model.toArray();

ActiveRecord는 단순한 배열이 아니기 때문입니다. , 직접 json_encoded될 수 없습니다. 그렇지 않으면 정보가 불완전합니다.

해결책: $model.toArray(); 이는 이를 간단한 배열로 변환하고 json_encoded할 수 있습니다.

2. 이름이나 기타 필드를 통해 직접 ActiveRecord ID를 가져옵니다.

$nIdcId = idc_info::model()->find(&#39;name like :name&#39;,array(&#39;:name&#39;=>"%".$strIdcName."%"))->id;
로그인 후 복사
이전에 자주 사용했던 방법은 (지금은 너무 지루하네요)

$idc = Idc::model()->find("...");
$id = $idc->id;
로그인 후 복사
3. 모델의 이해

$accModel = call_user_func(array(ActiveRecordName, &#39;model&#39;));
$model  = $accModel->findByPk($id);
로그인 후 복사
위는 Yii2 ActiveRecord 멀티 테이블 연관과 소개된 멀티 테이블 연관입니다. 테이블 연관 검색 구현에 대한 관련 지식을 얻는 데 도움이 되기를 바랍니다. 질문이 있는 경우 메시지를 남겨주시면 편집자가 시간 내에 답변해 드리겠습니다. 또한 PHP 중국어 웹사이트를 지원해 주신 모든 분들께 감사드립니다!

Yii2 ActiveRecord 다중 테이블 연관 및 다중 테이블 연관 검색 구현과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 추천
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿