CHAPTER 13 ■ DATABASE PATTERNS
$this->findByVenueStmt->fetchAll(), $this );
}
The findByVenue() method is identical to findAll() except for the SQL statement used. Back in the
VenueMapper, the resulting collection is set on the Venue object via Venue::setSpaces().
So Venue objects now arrive fresh from the database, complete with all their Space objects in a neat
type-safe list. None of the objects in that list are instantiated before being requested.
Figure 13–4 shows the process by which a client class might acquire a SpaceCollection and how the
SpaceCollection class interacts with SpaceMapper::createObject() to convert its raw data into an object
for returning to the client.
Figure 13–4. Acquiring a SpaceCollection and using it to get a Space object
Consequences
The drawback with the approach I took to adding Space objects to Venue ones is that I had to take two
trips to the database. In most instances, I think that is a price worth paying. Also note that the work in
Venue::doCreateObject() to acquire a correctly populated SpaceCollection could be moved to
Venue::getSpaces() so that the secondary database connection would only occur on demand. Here’s
how such a method might look:
// Venue
// namespace woo\domain;
// ...
function getSpaces() {
if (! isset( $this->spaces ) ) {
$finder = self::getFinder( 'woo\domain\Space' );
$this->spaces = $finder->findByVenue( $this->getId() );
}
return $this->spaces;
}
If efficiency becomes an issue, however, it should be easy enough to factor out SpaceMapper
altogether and retrieve all the data you need in one go using an SQL join.