Оптимизация запросов к БД при использовании ООП

sprit

Новичок
Оптимизация запросов к БД при использовании ООП

Возникла проблема при использовании ООП в PHP.
Существует несколько классов, таких как

Клиент - TCustomer
Счет - TInvoice
PHP:
class TCustomer{
	public  $ID;
	public  $Name;
	public  $Surname; 
	function __construct($CustomerID){
		global $DB;
		$this->ID = $CustomerID;
		list($this->Name,$this->Surname) = $DB->GetQuery("SELECT Name,Surname FROM Customers Where ID={$this->ID}");
	}
	function GetInvoices($DateFrom,$DateTo){
		global $DB;
		$ResArray = Array();
		$Res = $DB->Query("SELECT ID FROM Invoices Where CustomerID={$this->ID} AND Date BETWEEN '$DateFrom' AND $DateTO");
		while ($Row = $DB->Fetch($Res)){
			$ResArray = new TInvoice($Row['ID']);
		}
		$DB->Free($Res);
	}
}
class TInvoice{
	public $ID;
	public $Cost;
	function __construct($InvoiceID){
		global $DB;
		$this->ID = $InvoiceID;
		list($this->Cost) = $DB->GetQuery("Select Cost From Inoices Where ID={$this->ID}")
	}
}
Задача: создать сводный отчет по клиентам за период времени с отображением счетов.
Решение:
PHP:
$Res = $DB->Query("Select ID From Customers");
while ($Row = $DB->Fetch($Res)){
	$Customer =  new TCustomer($Row['ID']);
	$CustoemerInvoices =  $Customer->GetInvoice
	//....
	// формирование и вывод информации
}
Таким образом если 100 клиентов по 5 счетов итог 1000!!! запросов к Базе.
Если без применения ООП всего 2 (Выбрать клиентов и счета этих клиентов).

Вопрос: Что необходимо здесь изменить чтобы оптимизировать скрипт с сохранением ООП.

Подскажите пожалуйста, я уже просто не знаю что делать. Нигде это я не нашел.
Если есть какой-нибудь материал по такому случаю подскажите.
 

ZN

Новичок
я бы написал класс TCustomerHandler с методом getObjects, который принимал бы условия выборки, на их основании формировал бы запрос, исполнял его, потом фетчил бы результаты этого запроса, создавал объекты TCustomer, заполнял их результатами из фетча и возвращал массив объектов TCustomer
 

bgm

 
Вариант первый: убери запросы к базе из классов вообще - делай выборку двумя запросами (а можно и одним), потом создавай соответствующие экземпляры классов.

Вариант второй: делаешь третий класс, который будет содержать условия выборки - промежуток дат, условия на имена и фамилии клиентов, условие на стоимость счёта и т.д., а потом одним (или двумя) запросами получаешь необходимую информацию.

P.S. Кстати - TCustomer для конкретного клиента может уже содержать массив счетов - объекты TInvoice.
 

sprit

Новичок
ZN<<<
В принципе до недавного времени, это бы вполне устроило, но
1) при изменении класса TInvoice приходится переписавать класс
TCustomerHandler и TCustomer.
2) Для каждого отчета создавать свой собственный класс и добавлять/модифицировать, в соответствии с этим отчетам, параметры TCustomerHandler.
Т.е. приходится переписавать очень большую часть кода (один отчет может содержать более 10 различных классов, с различными выборками)
bqm<<<
Вариант первый: Тогда придется при изменении одной таблицы придется переписавать как минимум половину отчетов и форм.
Вариант второй: в принципе сводится к созданию класса, формирующий отчет.

В данный остановился пока на:
создаю для каждого отчета/формы свой класс, делаю выборку, которая создает нужные классы, в конструктор в качестве параметра, передается значения внутренних полей, типа
PHP:
$Customer = TCustomer(Array('ID'=>1,'Name'=>'Test','Invoices'=>Array(Array('ID'=>1,'Cost'=>2.2),Array('ID'=>2,'Cost'=>4.4))));
Если какие поля не заполнены класс обращается к БД. Т.о. при изменении(внесение дополнительных полей) таблицы все не рухнет, но снизится производительность.

Но, если честно, конечно хотелось бы придумать что-то более совершенное, т.к. на проброску всех свойств через вложения уходит просто уйма времени, а на автозаполение классов, еще больше.

У меня была идея собирать запросы, а потом их отправлять к бд, но я не знаю как это реализовать.
 
Сверху