如何管理数据层中的SQL语句

时间:2009-03-30 09:37:33

标签: php sql

在PHP项目中,我们已经将业务逻辑与数据库访问分开了。所有数据库任务都封装在按数据库和主题分组的不同数据库类中。 这些类看起来非常可怕,一半的源代码是SQL字符串,它们充满了params等等。我们考虑将SQL放在“其他”位置,如资源文件或其他东西。什么是最佳实践,你知道PHP的任何支持工具/库吗?

亲切的问候

斯蒂芬

4 个答案:

答案 0 :(得分:2)

您应该尽可能使用存储过程。这样可以增强性能,安全性和代码维护。这应该是你的第一个方法。

如果您仍想将SP查询与DAL分开,为什么不将它们存储在数据库中?将SQL查询存储在数据库中进行抽象可能看起来很奇怪,因为需要查询来提取其他查询。这实际上是一种非常常见的方法,您可以选择符合特定条件的查询,并可能(如果需要)动态构建查询。

另一种方法可能是创建Query-classes,其中查询是动态构建的;

class FruitQuery {
    ...
    public function addTypeCriteria($type) {
        $this->internalSQLCriterias[]  = "fruit=:type";
        $this->internalSQLParameters[] = array(':type', $type);
    }
    ...
    public function create() {
        $this->internalSQLQuery = "SELECT ... FROM Fruits";

        if (sizeof($this->internalSQLCriterias) > 0) {
            $this->internalSQLQuery .= " WHERE ";
            $moreThanOne = '';

            foreach ($this->internalSQLCriterias as $criteria) {
                $this->internalSQLQuery .= $moreThanOne . $criteria;
                $moreThanOne = " AND ";
            }
        }
    }
    ...
    public function execute() {
        /* Bind the parameters to the internalSQLQuery, execute and return results (if any) */
    }
...

这个类绝对不是完整的,你可能想重新考虑它的结构 - 但你可能会得到我想要的观点。 :)当然,您必须过滤“查询”构建器的输入以避免安全漏洞!

答案 1 :(得分:2)

我不懂PHP,但根据我对其他语言的经验,我可以告诉你:数据访问层是architecture astronauts的主要目标。有这么多“最佳实践”,没有一个是最好的。在设计DAL时,很容易陷入过度抽象的陷阱。只要你需要就可以了。

我几乎总是使用存储过程以避免意大利面条代码并简化数据库中的授权,而不是出于性能原因;由于数据库引擎何时以及如何准备它们的复杂性,存储过程的性能提升很难确定。另一方面,如果我需要编写一个非常灵活的数据库操作(比如在具有许多输入的搜索屏幕上),我有时会将SQL放在代码中。无论你把它放在哪里,它有时会变得难以理解。你必须在某个地方做这项工作。

如果您没有(不必要地)混合使用SQL和过程代码,请将SQL放在最适合应用程序范围和规模的位置。抱歉,我无法解答有关PHP工具和库的问题,但我希望这有用。

答案 2 :(得分:0)

好吧,您可以始终使用PDO在不同数据库中使用一致的API并编写portable SQL statements

另一种选择是使用数据库抽象层,例如Zend_DB

答案 3 :(得分:0)

您的数据库访问层中几乎不应该有任何SQL,因为它应该只是抽象与数据库的通信,而不管它正在通信的实际SQL。

在现在着名的MVC模式中,您的业务逻辑 通常包含构成模型层的SQL。

将所有这些“宗教”定义放在一边,你现在拥有的是中等正常的,最终会成堆的SQL。 SQL必须存在于某个地方。根据您的优先级和性能要求,我会做什么(按性能折衷排序):

  1. 如果SQL中有明显的重复,我会进行快速重构迭代以隐藏所有常见的SQL内部方法。这些方法不一定要执行它,而只是构建它。这一切都取决于您的应用程序以及SQL的复杂程度。如果你没有与数据库进行实际通信的底层,那么重构的一部分可能就是添加它。

  2. 我会考虑使用“查询”构建器。这是性能和灵活性之间的非常好的平衡。您只能在ORM或数据库访问层(如Zend_Db及其子组件),Propel和/或Doctrine中找到查询构建器。因此,您可以将查询构建器从其中一个端口移植到项目中而不使用整个层(这实际上不应该很难,因为它们都是基于PDO的)。这不应该增加任何明显的性能问题。

  3. 我会考虑Doctrine ORM。这虽然对性能有相当大的影响。但是,最终会得到非常易于维护的代码。

  4. 最后,我永远不会考虑将SQL放入资源或类似的东西。