数据映射器模式:来自服务层的复合查询 [英] Data Mapper Pattern: Complexe query from Service Layer

查看:113
本文介绍了数据映射器模式:来自服务层的复合查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Zend Framework中唱了数据映射器模式。到目前为止,这一切都很好,但现在我已经到了需要你的帮助/意见的地步。所以让我们从代码开始:



我们得到了一个有几个人的表:

  CREATE TABLE`persons`(
`id` int(11)NOT NULL AUTO_INCREMENT,
`name` varchar(50)NOT NULL,
`age` int(3) NOT NULL,
`haircolor` varchar(20)DEFAULT NULL,
PRIMARY KEY(`id``),
);

现在我尝试选择所有的人,有棕色的头发。我在ServiceLayer中使用以下方法

  public function getPeopleByHaircolor($ hair){
return $ this-> getMapper() - > fetch('haircolor =?',$ hair);
}

Mapper中的方法如下所示:

  public function fetch($ condition,$ value){
$ resultSet = $ this-> getTable() - > fetchAll($ this - > getTable() - > select() - > where($ cond,$ value));
$ entries = array();

foreach($ resultSet as $ row){
$ entry = new Default_Model_Person();
$ entry-> id = $ row-> id;
$ entry-> name = $ row-> name;
[...]
}
return $ entries;
}

我认为我使用这种方法跟踪数据映射器模式...






现在问题:



我想选择有棕色头发的人,年龄小于20岁。
那么我该怎么做呢?我的尝试:

  public function getTeens($ hair){
$ rows = $ this-> getMapper() - > fetch('haircolor =?',$ hair);
$ return = array();
foreach($ rows as $ row){
if((int)$ row-> age< 20)$ return [] = $ row;
}
return $ return;
}

但是,如果您收到更多变量,例如棕色头发的人, 20yrs,名字叫Foo Bar,我需要越来越多的方法和/或foreach循环。






我的问题:



如何在Data Mapper模式中执行此操作?如果我做一个本机SQL查询,如$ serviceLayer-> mapper-> table-> qry('SELECT ...'),这是否打破了数据映射器模式?
我不喜欢那些额外的foreach循环,感觉我做错了,所以我写了这个问题。

解决方案

确实,在两个条件下,在一个条件下查询不合适,然后在迭代时对其他对象进行过滤。它给你两个条件没有明确的方法。并且实现分页适配器变得相当凌乱。



似乎我认为问题是你的mapper fetch()方法支持只允许单个条件。所以:


  1. 修改签名以支持一系列条件。


  2. 或者,您可以为每个增强的提取方法创建一个单独的映射器方法,例如: fetchByHairAndAge($ hair,$ age)等。



I'm sing the Data Mapper Pattern in Zend Framework. This works well so far, but now I got to a point where I need your help/opinion. So let's start with the Code:

We got a table with several Persons:

CREATE TABLE `persons` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `age` int(3) NOT NULL,
  `haircolor` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id``),
);

Now I try to select all people, that have brown hair. I use the following method in the ServiceLayer

public function getPeopleByHaircolor($hair) {
  return $this->getMapper()->fetch('haircolor = ?', $hair);
}

The method in the Mapper looks like this:

public function fetch($condition, $value) {
  $resultSet = $this->getTable()->fetchAll($this->getTable()->select()->where($cond, $value));
  $entries = array();

  foreach($resultSet as $row) {
    $entry = new Default_Model_Person();
    $entry->id   = $row->id;
    $entry->name = $row->name;
    [...]
  }
  return $entries;
}

I think I follow the Data Mapper Pattern with this methods...


Now the Problem:

I want to select Persons, that have brown hair AND that are younger than 20 yrs. So how can I do that? My try:

public function getTeens($hair) {
  $rows = $this->getMapper()->fetch('haircolor = ?', $hair);
  $return = array();
  foreach($rows as $row) {
    if((int)$row->age < 20) $return[] = $row;
  }
  return $return;
}

But if you get more variables, like "people with brown hair, younger than 20yrs and with the name 'Foo Bar'", I need more and more methods and/or foreach loops.


My Question:

How would you do this in the Data Mapper Pattern? If I do a native SQL query like $serviceLayer->mapper->table->qry('SELECT ...'), is this breaking the Data Mapper Pattern? I don't like those additional foreach loops and it feels like I'm doing something wrong, so I wrote this question.

解决方案

Indeed, for two conditions, it inadvisable to query on one condition and then filter on your other while you iterate. It leaves you no clear approach for more than two conditions. And implementing pagination adapters becomes pretty messy.

Seems to me that the issue is that your mapper fetch() method supports permits only a single condition. So:

  1. Modify the signature to support an array of conditions.

  2. Alternatively, you could create a separate mapper method for each enhanced fetch method, ex: fetchByHairAndAge($hair, $age), etc.

这篇关于数据映射器模式:来自服务层的复合查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆