簡體   English   中英

當類DAO具有使用相同結果的方法時,減少查詢數量的最佳方法是什么?

[英]What the best way to reduce the number of queries when the Class DAO have methods that use the same result?

我有一個幫助類DAO(我不知道是否可以這樣做),用於從MySQL DB獲取Categories,該結構基本上是這樣的:

<?php

require_once '../include/PDOConnectionFactory.php';

class CategoryDAO extends PDOConnectionFactory
{
    /**
     *
     * @var PDO $conn 
     */
    private $conn;

    public function __construct()
    {
        $this->conn = PDOConnectionFactory::getConnection();
    }
}
?>

此類具有以下方法(然后是某些方法):

getMaxLevel()
getAllCategories()
getAllCategoriesOfLevel($level)
haveChildCategory($categoryName)
getIdCategory($categoryName)
getCategoryName($idCategory)

編輯 :方法getAllCategories()的主體類似於下面的內容,並且此類的幾乎所有方法都將其稱為getAllCategories():

public function method()
    {
        try {
            $stmt = $this->conn->prepare("SELECT * FROM category");
            $stmt->execute();
            $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            echo $e->getMessage();
        }

        return $result;
    }

我不知道減少查詢冗余的最佳方法是什么,我認為:

  1. 實例化類對象,調用getAllCategories()並調用其他通過參數傳遞結果的方法。
  2. 有一個私有屬性,其結果為getAllCategories(),在由__construct()創建對象時進行填充。

但是在這些情況下,我看到了這個缺點:

  1. 最好不要使用OOP。
  2. DB UPDATE或INSERT之后,該對象可能已過時。

如果我的問題在OOP中是概念性的,請告訴我。

從效率的角度來看,您的DAO聽起來真是個壞主意。 就我個人而言,我找不到提供任何真正價值的數據訪問對象。 什么時候拉類別名稱而不拉類別ID? 您最好一次查詢整行,然后編寫一些專門的查詢來執行其他功能。

該響應取決於當前的查詢結構,其中沒有條件

class CategoriaDAO extends PDOConnectionFactory
{
    /*DB Connection, static member since you only need one connection*/
    private static $dbConnection;

    /*Sql result set, static since there is not conditonal and only a single table used*/
    private static $resultSet;

    private static function getConnection()
    {
            /*Connect to mysql db, set CategoriaDAO::dbConnection; */
    }

    private static function populateResultSet()
    {
            /*Run query and populate resultSet - either as sql result or parse to array - your call*/
    }
    /**
     *
     * @var PDO $conn 
     */
    private $conn;

    public function __construct()
    {
                /*Get sql connection if one hasn't already been established*/
                if(!CategoriaDAO::dbConnection)
                        $this->conn = PDOConnectionFactory::getConnection();
    }
}

其背后的思考過程是,由於結果始終是相同的(暫時忽略,更新,插入,刪除),因此不需要在每個對象中保留結果的副本。

如您所指出的,表更新將使存儲的結果集與對象不同步; 在這里,我想回溯一下,如果給定對象的結果集僅在創建時是最新的,則使用普通對象成員。

值得一提的是,是否要更改查詢以及是否更改查詢,是否需要更改,都需要生成對象成員。 如果查詢沒有變化,那么除了前一點之外,沒有什么可擔心的。 如果確實發生更改,以下示例將或多或少地涵蓋您的選項。

class Foo{
    private $someMember;

    /*
        $params = Associative array of fields and values
    */
    private static buildAndRunQuery($params)
    {
        /*Build sql query based on the given params Array()*/
    }
    public __construct($someMemebrValue)
    {
        $this->someMember = $someMemberValue;
        Foo::buildAndRunQuery(Array("fieldName" => $this->someMember));
    }
}

在此示例中,您仍在使用靜態方法來生成查詢,但是您要為流程傳遞非靜態成員/此時(請參閱有關創建時對象最新的注釋),您可以存儲靜態成員中的結果,或將它們傳遞回__construct()函數並存儲對象實例。

這樣一來,您所使用的查詢可能會比簡單地請求某些字段要復雜得多,因此創建多維數組以傳遞給靜態函數的麻煩將超過其價值。 在這種情況下,您可以將buildAndRunQuery()拆分為buildQuery()-實例方法和runQuery()靜態方法,例如。

class Foo{

    private $someMember;

    /*
        $params = Associative array of fields and values
    */
    private static runQuery($query)
    {
        /*Build sql query based on the given params Array()*/
    }

    private function buildQuery()
    {
        /*Construct your query here and either return calling method or store in instance member*/
         /*Either*/
            return <Constructed query>;
        /*Or*/
           $this->query = <Constructed query>;
    }

    public __construct($someMemebrValue)
    {
        $this->someMember = $someMemberValue;
        /*As per buildQuery() comment either:*/
            Foo::runQuery($this->buildQuery());
        /*Or*/
            Foo::runQuery($this->query);
    }
}

在這種情況下,在調用Foo :: runQuery()之前,有兩個選項可以處理生成的查詢。

當然,總有可能您不想以同步方式或實際上在構造函數中創建和運行查詢。

總而言之,我個人認為對於與對象本身無關的服務進行交互的方法(例如Sql或可能的DOMDocument或類似的對象交互),最好在相關且不最終使您不知所措的情況下使用靜態方法。討厭你的臉(不必要地復雜等)。 當然,所有這些都需要在每個班級的基礎上加以考慮。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM