좋아요, 저는 DBIx :: Class를 처음 접했습니다. 나는 다음과 같이 일대 다 관계를 설정했습니다 :Perl : DBIx :: Class Beginner - 서브 세트 관계 및 프리 페치
User -> has_many -> Addresses
좋습니다. 나는 쿼리를 할 수 있고 다음과 같이 JOIN 된 테이블을 프리 페칭이라고 부른다 :
Foo::DBIC->storage->debug(1); # output SQL to STDOUT
my $user = Foo::DBIC->resultset('Users')->search({}, {
prefetch => [ 'addresses' ],
join => [ 'addresses' ],
rows => 1
})->single;
for my $address ($user->addresses->all) {
say $address->zip_code;
}
두 개의 테이블, 하나의 SQL 쿼리 (디버그를 통해 검증 됨). 모든 것이 잘됩니다.
그러나 이제 특정 조건에 따라 하위 집합을 반환하는 Foo :: DBIC :: Result :: Users에 두 가지 오버로드 메서드를 작성하려고한다고 가정 해 봅시다. 여기에이 사용자 클래스에 추가 한 내용은 다음과 같습니다 내가 지금 같은이 오버로드를 호출 할 수 있습니다
sub home_addresses {
my $self = shift;
return $self->search_related('addresses', { address_type => 'home' });
}
sub business_addresses {
my $self = shift;
return $self->search_related('addresses', { address_type => 'business' });
}
, 그들은 작동 :
for my $address ($user->home_addresses->all) {
say $address->zip_code;
}
그러나,이 내가 프리 페치했다고 사실을 무시 내 조인, 그리고 추가 쿼리를 수행합니다 (마치 내가 프리 페치하고 아무것도 참가하지 않은 것처럼).
그럼, 내 질문은 : 관련 테이블의 하위 집합을 반환하지만 이미 prefetched 조인을 사용하는 오버로드 메서드는 어떻게 정의합니까? (단지 preheetch에 WHERE 절을 추가) ...
내 문제는 관련된 테이블 하위 집합을 반환하는 많은 오버로드 된 메서드가있는 경우 쿼리 수가 폭발 할 수 있습니다. 특히 루프 내에서 호출하는 경우.
나는 이것을하는 이유가 있습니다. 물론 추한 것입니다. 내 실생활 스키마는 사용자와 주소보다 훨씬 많이, 많이, 많이 엉망이며, 나는 가능한 한 가장 추악한 것을 추상화하려고 노력하고있다.
감사합니다.
데이터베이스를 다시 쿼리하지 않으려 고하므로 DBIC 메서드를 호출하는 이유는 무엇입니까? 이득 쿼리를 얻지 않고, 펄 함수 (예 : grep)로 반환 된 데이터를 필터링하는 메서드를 작성하면됩니다. – MkV
왜 내가 오버로드 된 메서드라고 부르는지 궁금합니다. Perl에서 오버로드하는 것은 예를 들어 객체가 숫자로 반환되어야하는 것을 정의 할 때입니다. –
나는 단어를 빨아 때문에. "열 접근 자 오버로드"라는 측면에서 생각하고 있었지만 실제로는 어쨌든 새로운 접근 자 메서드를 만들었습니다. 어쨌든, 당신은 내가 무엇을 의미하는지 알았습니다. –