[英]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.