Just wanted to also say that I have been using the repository pattern in
these situations where you need an interface to handle all these
specialized queries. If your mapper is starting to get bloated.. then
you should really look into the repository which can take some of the
responsibility of translating these criteria commands, and you mapper
can go back to translating business logic to sql layer (Zend_Db_Table or
Doctrine Record, PEAR DB, etc)
On 4/15/2010 10:31 AM, keith Pope wrote:
On 15 April 2010 14:48, Matthew Weier O'Phinney<[email protected]> wrote:
-- Ralf Eggert<[email protected]> wrote
(on Thursday, 15 April 2010, 02:10 PM +0200):
I have a question regarding a model infrastructure that uses models,
data sources, data mappers and a service layer. I like this concept a
lot but am still thinking about one issue.
I want to get a list of all blue articles which have been ordered by
users from Germany and have been paid last month. Thinking about the
database this will definitely be a rather complex database join about at
least three tables (articles, users, order). Lets call this method
fetchBlueArticlesOrderedByGermanyPaidLastMonth().
Where should this method be located?
- in the data source (Zend_Db_Table class)
- in the model
- in the data mapper
- in the service layer
I could find pros and cons for each solution if I want to. But what do
others think?
I typically think of this as a job for the mapper, as it's mapping the
data source to objects. That gives you the flexibility of either
wrapping it in your service layer (I do this so I can return a paginator
object) or simply calling it as a method off your mapper.
I have started to use the repository pattern lately this seems to work
well, so you have:
- dbTable
- mapper
- model
- repository
- service
So now for highly specialized queries I would have them inside the
repository, not sure about
fetchBlueArticlesOrderedByGermanyPaidLastMonth() but I would have a
pretty descriptive method name :) I have implemented a criteria object
so the rules can be easily added at runtime, so maybe something like
getOrderedArticlesForMonth(). Using the repo you can then do something
like:
$articleOrderRepo = new Kp_Model_Repository_ArticleOrders();
$articleOrderRepo->addCriteria(new
Kp_Domain_Repository_Criteria('color', '= ?', 'blue'));
$articleOrderRepo->addCriteria(new
Kp_Domain_Repository_Criteria('country', '= ?', 'Germany'));
$articleOrderRepo->getOrderedArticlesForMonth(10);
The only thing here is that the criteria/repository are fairly one
dimensional so complex joins would need to be placed inside the mapper
as its hard to accurately generate the correct joins. Also sometimes
for large queries, for example when doing a export of all order for a
year, I have a getRaw type method on the repository, this will then
return data instead of objects to stop memory errors.
--
Matthew Weier O'Phinney
Project Lead | [email protected]
Zend Framework | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc