Yii 2 에서 join,joinwith 다 중 표 관련 조회 사용 하기

표 구조
현재 고객 표,주문서,도서 표,작가 표 가 있 습 니 다.
클 라 이언 트 테이블 Customer(id customername)
주문서 Order(id ordername customer_id book_id)
도서 목록(id bookname author_id)
작성 자 표(id authorname)
모델 정의
다음은 이 네 개의 모델 의 정의 입 니 다.그 중의 관련 만 적 습 니 다.
Customer

class Customer extends \yii\db\ActiveRecord
{
//          ,                ,         
public function getOrders()
{
//                 ,
//              customer_id,     id  
return $this->hasMany(Order::className(), ['customer_id' => 'id']);
}
}
Order

class Order extends \yii\db\ActiveRecord
{
//         
public function getCustomer()
{
//                  
//
return $this->hasOne(Customer::className(), ['id' => 'customer_id']);
}
//          
public function getBooks()
{
//                  
//
return $this->hasMany(Book::className(), ['id' => 'book_id']);
}
}
Book

class Book extends \yii\db\ActiveRecord
{
//        
public function getAuthor()
{
//                  
return $this->hasOne(Author::className(), ['id' => 'author_id']);
}
}
Author

class Autor extends \yii\db\ActiveRecord
{
}
hasmany,hasOne 사용
Yii 2 의 표 간 의 관 계 는 두 가지 로 두 모델 간 의 관 계 를 지정 합 니 다.
한 쌍 다:hasmany
일대일:hasOne
결과 반환:이 두 가지 방법의 반환 결 과 는 모두 yii\db\ActiveQuery 대상 입 니 다.
첫 번 째 매개 변수:연 결 된 모델 의 클래스 이름 입 니 다.
두 번 째 매개 변수:하나의 배열 입 니 다.그 중에서 키 는 관련 모델 의 속성 이 고 값 은 현재 모델 의 속성 입 니 다.
관련 사용
현재 우 리 는 한 고객 의 모든 주문 정 보 를 얻 었 다.

//         
$customer = Customer::findOne(1);
$orders = $customer->orders; //    Customer        (getOrders())             。
위의 두 줄 코드 는 다음 과 같은 sql 문 구 를 생 성 합 니 다.

SELECT * FROM customer WHERE id=1;
SELECT * FROM order WHERE customer_id=1;
관련 결과 캐 시
만약 고객 의 주문 이 바 뀌 었 다 면,우 리 는 다시 호출 할 것 이다.

$orders = $customer->orders;
다시 주문 서 를 받 았 을 때 변 함 이 없다 는 것 을 알 게 될 것 이다.$customer->orders 를 처음 실행 할 때 만 데이터베이스 에 가서 조회 한 다음 결 과 를 캐 시 합 니 다.나중에 조회 할 때 sql 을 실행 하지 않 기 때 문 입 니 다.
그럼 제 가 sql 을 다시 실행 하고 싶다 면 어떻게 하 시 겠 습 니까?실행 가능

unset($customer->orders);
$customer->orders;
그리고 데이터베이스 에서 데 이 터 를 찾 을 수 있 습 니 다.
다 중 연결 정의
마찬가지 로 저 희 는 Customer 에서 여러 개의 관 계 를 정의 할 수 있 습 니 다.
총 100 개 이상 의 주문 서 를 되 돌려 준다 면.

class Customer extends \yii\db\ActiveRecord
{
public function getBigOrders($threshold = 100)
{
return $this->hasMany(Order::className(), ['customer_id' => 'id'])
->where('subtotal > :threshold', [':threshold' => $threshold])
->orderBy('id');
}
}
관련 된 두 가지 접근 방식
하면,만약,만약...

$customer->bigOrders
100 이상 의 모든 주문 서 를 받 을 수 있 습 니 다.200 이상 의 주문 서 를 되 돌려 주 려 면 이렇게 쓸 수 있 습 니 다.

$orders = $customer->getBigOrders(200)->all();
위 에서 보 듯 이 하나의 연관 성 을 방문 할 때 두 가지 방법 이 있 습 니 다.
함수 로 호출 하면 ActiveQuery 대상($customer->getOrders()->all()을 되 돌려 줍 니 다.
속성 으로 호출 하면 모델 의 결 과 를 되 돌려 줍 니 다($customer->orders)
with 의 사용 은 다음 코드 를 보면 고객 의 주문 서 를 찾 는 것 입 니 다.

//   sql  : SELECT * FROM customer WHERE id=1
$customer = Customer::findOne(1);
//  sql:SELECT * FROM order WHERE customer_id=1
$orders1 = $customer->orders;
//      sql,           
$orders2 = $customer->orders;
만약 지금 우리 가 100 명의 사용 자 를 꺼 내 서 모든 사용자 의 주문 서 를 방문 하려 고 한다 면,위 에서 알 고 있 는 바 와 같이 우 리 는 다음 과 같은 코드 를 쓸 수 있 습 니 다.

//   sql  : SELECT * FROM customer LIMIT 100
$customers = Customer::find()->limit(100)->all();
foreach ($customers as $customer) {
//   sql: SELECT * FROM order WHERE customer_id=...
$orders = $customer->orders;
//     。。。
}

그러나 이렇게 쓰 려 면 foreach 의 모든 순환 에서 sql 을 실행 하여 데이터 베 이 스 를 조회 합 니 다.$customer 마다 대상 이 다 르 기 때문이다.
위의 문 제 를 해결 하기 위해 yii\db\ActiveQuery::with()를 사용 할 수 있 습 니 다.
그 중에서 width 의 매개 변 수 는 관계 의 이름 이 고 model 에서 정 의 된 getOrders,getCustomer 의 orders 와 customer 입 니 다.

//    sql: SELECT * FROM customer LIMIT 100;
// SELECT * FROM orders WHERE customer_id IN (1,2,...)
$customers = Customer::find()->limit(100)
->with('orders')->all();
foreach ($customers as $customer) {
//               sql 
$orders = $customer->orders;
// ...handle $orders...
}
만약 select 를 사용 하여 되 돌아 오 는 열 을 지정 한다 면,되 돌아 오 는 열 에 연 결 된 모델 의 관련 필드 가 포함 되 어 있 는 지 확인 해 야 합 니 다.그렇지 않 으 면 연 결 된 표 의 Model 로 돌아 가지 않 습 니 다.

$orders = Order::find()->select(['id', 'amount'])->with('customer')->all();
// $orders[0]->customer       null
//      select           (customer)         。
//     customer_id,$orders[0]->customer          
$orders = Order::find()->select(['id', 'amount', 'customer_id'])->with('customer')->all();
with 필터 조건 추가
고객 이 100 이상 인 주문 서 를 조회 하 다.

//    sql: SELECT * FROM customer WHERE id=1
$customer = Customer::findOne(1);
//         sql  :SELECT * FROM order WHERE customer_id=1 AND subtotal>100
$orders = $customer->getOrders()->where('subtotal>100')->all();
100 개의 고객 을 조회 하 는 모든 고객 의 총합 이 100 보다 큰 주문

//         sql  : 
// SELECT * FROM customer LIMIT 100
// SELECT * FROM order WHERE customer_id IN (1,2,...) AND subtotal>100
$customers = Customer::find()->limit(100)->with([
'orders' => function($query) {
$query->andWhere('subtotal>100');
},
])->all();
여기 서 width 의 인 자 는 배열 이 고 키 는 연 결 된 이름 이 며 값 은 반전 함수 입 니 다.
즉,orders 와 연 결 된 ActiveQuery 에 대해$query->and Where('subtotal>100')를 한 번 더 실행 합 니 다.
joinWith 로 표 연결 하기
우 리 는 모두 join on 으로 여러 표 간 의 관 계 를 쓸 수 있다 는 것 을 안다.먼저 yii 2 중 joinWit 의 성명 을 살 펴 보 겠 습 니 다.

joinWith( $with, $eagerLoading = true, $joinType = 'LEFT JOIN' )
$with 데이터 형식 은 문자열 이나 배열 입 니 다.문자열 이 라면 모델 에 정 의 된 관련 이름(하위 연결 가능)입 니 다.
배열 이 라면 키 는 model 에서 getXXX 형식 으로 정 의 된 연결 이 고 값 은 이 관련 에 대한 추가 적 인 리 셋 작업 입 니 다.
$eagerLoading 이$with 에 연 결 된 모델 의 데 이 터 를 불 러 올 지 여부 입 니 다.
$join Type 연결 형식,사용 가능 한 값:LEFT JOIN,INNER JOIN,기본 값 은 LEFT JOIN

//         Left join     。
//       ,     ID     ID   
$orders = Order::find()->joinWith('customer')->orderBy('customer.id, order.id')->all();
//         Inner join     
//          
$orders = Order::find()->innerJoinWith('books')->all();
//   inner join   order   books   customer  。
//   custmer          :  24              
$orders = Order::find()->innerJoinWith([
'books',
'customer' => function ($query) {
$query->where('customer.created_at > ' . (time() - 24 * 3600));
}
])->all();
//   left join   books  ,books    left join    author  
$orders = Order::find()->joinWith('books.author')->all();
실현 에 있어 Yii 는 먼저 JOIN 조회 조건 을 만족 시 키 는 SQL 문 구 를 실행 하고 결 과 를 메 인 모델 에 채 운 다음 에 모든 관련 문 구 를 실행 하고 해당 하 는 관련 모델 을 채 웁 니 다.

// Order books   inner join ,    books       
$orders = Order::find()->innerJoinWith('books', false)->all();
조건 부
연결 을 정의 할 때 on 조건 도 지정 할 수 있 습 니 다.

class User extends ActiveRecord
{
public function getBooks()
{
return $this->hasMany(Item::className(), ['owner_id' => 'id'])->onCondition(['category_id' => 1]);
}
}
joinWith 에서 사용

//      (User)   , SELECT user.* FROM user LEFT JOIN item ON item.owner_id=user.id AND category_id=1
//                  SELECT * FROM item WHERE owner_id IN (...) AND category_id=1
//                on  。
$users = User::find()->joinWith('books')->all();
join 작업 을 사용 하지 않 으 면 with 를 사용 하거나 직접 속성 으로 연결 에 접근 합 니 다.이 럴 때 on 조건 은 where 조건 으로

// SELECT * FROM user WHERE id=10
$user = User::findOne(10);
총결산
우선 모델 에서 연결 을 정의 해 야 합 니 다(예 를 들 어 getOrders 의 Orders 는 하나의 연결 입 니 다)
그리고 with 나 join With 에서 모델 에 정 의 된 연결 을 사용 합 니 다.
이 중 관련 을 사용 할 때 리 셋 방법 도 지정 할 수 있다.
그리고 관련,with,join With 에 where 또는 on 조건 을 지정 할 수 있 습 니 다.
이 부분 은 사실 매우 많 고 복잡 하 며 어떤 기능 은 다 말 하지 못 했다.예 를 들 어 세 개의 표 관련,역 관련 등 이다.
가장 기본 적 인 조작 도 대체로 이것들 이다.또 알 고 싶 은 곳 이 있 으 면 댓 글 을 달 아 소통 할 수 있다.
위 에서 말씀 드 린 것 은 편집장 님 께 서 소개 해 주신 Yii 2 의 다 중 표 관련 조회(join,joinwith)에 관 한 지식 입 니 다.여러분 께 도움 이 되 셨 으 면 좋 겠 습 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 님 께 서 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기