干和类似的查询

时间:2009-02-27 01:51:11

标签: mysql dry

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

$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?编写一个用于执行此类查询的类(使用构造函数params或setter for table,column,bound变量等)然后在我的应用程序中重用它似乎没有意义。但与此同时,我无法摆脱这种唠叨的感觉,即我在重复自己。

也许只是因为只有很多方法可以编写一个简单的查询,并且可以预期会有一定程度的重复。

思想?

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

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

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

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

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

(PS。总是喜欢组合而不是继承。对可以“运行”对象的类使用继承没有任何好处。

答案 2 :(得分:0)

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

有两种通用解决方案。第一种是将调用抽象为所有(或大多数)类似查询。然后再次进行另一组查询。然后到另一个。等等。不幸的是,这会导致许多块执行相同的操作:调用查询,检查问题,组合结果集,将其传回。这是一个DAL,但只有一种。它也没有扩展。

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