[英]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;
}
我不知道減少查詢冗余的最佳方法是什么,我認為:
但是在這些情況下,我看到了這個缺點:
如果我的問題在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.