3

在一个特定的应用程序上工作,我一次又一次地编写非常相似的查询。它们并不完全相同,但形式非常相似,并且嵌入在几乎相同的代码块中,例如

$Mysqli = new mysqli;
if ($Stmt = $Mysqli->prepare("SELECT foo 
                              FROM tblFoo 
                              WHERE something = ?")) {
    $Stmt->bind_param('s', $this->_something);
    $Stmt->execute();
    if (0 != $Stmt->errno)
        throw new Exception("blah, blah, blah");
    $Stmt->bind_result($foo);
    while ($Stmt->fetch()){
        $this->_foos[] = new Foo($foo);
    }
    $Stmt->close();
    } else {
        throw new Exception("blah, blah, blah"););
    }
}

后来,在其他地方......

$Mysqli = new mysqli;
if ($Stmt = $Mysqli->prepare("SELECT bar, baz 
                              FROM tblBar 
                              WHERE somethingElse = ?")) {
    $Stmt->bind_param('s', $this->_somethingElse);
    $Stmt->execute();
    if (0 != $Stmt->errno)
        throw new Exception("blah, blah, blah");
    $Stmt->bind_result($bar, $baz);
    while ($Stmt->fetch()){
        // do something else with $bar and $baz
    }
    $Stmt->close();
    } else {
        throw new Exception("blah, blah, blah"););
    }
}

...然后另一个,在其他地方另一个...等等。

这真的违反了 DRY 吗?编写一个类来执行这种查询(使用构造函数参数或表、列、绑定变量等的设置器)然后在我的整个应用程序中重用它似乎没有意义。但与此同时,我无法摆脱这种我在重复自己的唠叨感。

也许只是写一个简单的查询的方法只有这么多,并且像这样的一定数量的重复是可以预料的。

想法?

4

3 回答 3

1

很多人正是这样做的。创建一个代表每个表的类,它们都继承自同一个类。基类可以处理加载和保存数据。因此,如果要加载数据,只需调用 load 方法即可。您可以通过对象的属性设置和访问字段值。

还有像hibernate这样的库可以为你处理很多脏活。

于 2009-02-27T01:59:05.657 回答
1

我会说这是违规行为。看一眼您的代码(除非我遗漏了什么),除了字符串“foo”和“bar”(重复几次)和您的实际业务逻辑之外,这两个语句是相同的。

至少你可以提取它。更重要的是,应该提取所有 SQL 字符串。对我来说,它们似乎更像是数据而不是代码。如果你有一个 SQL 字符串、表等数组——那会使重构更加明显吗?

(从代码中提取字符串和其他数据是开始重构的好方法)

一种可能性是,如果您有一个具有表名的对象和一个包含您的业务逻辑的方法,您可以将它传递给一个带有所有样板的“处理器”(这是您在那里拥有的所有其余代码)。

我认为这可能会使它变干。

(PS。总是更喜欢组合而不是继承。在可以“运行”您的对象的类上使用继承没有任何优势)

于 2009-02-27T02:02:46.100 回答
0

您遇到了模块化的第一个愿望。:-)

有两种通用解决方案。第一个是抽象对所有(或大部分)类似查询的调用。然后再进行另一组查询。然后到另一个。等等。不幸的是,这导致许多块做同样的事情:调用查询,检查问题,组装结果集,将其传回。这是一个 DAL,但只是一种。它也无法扩展。

第二种解决方案是抽象进行查询并返回结果的过程,然后在此之上抽象数据访问(这基本上意味着您构建了一些组装 SQL 的东西)。这更有可能成为一个合适的 ORM 而不是一个简单的 DAL。扩展它要容易得多。

于 2009-02-27T03:43:38.463 回答