Mechanizmy wykorzystujące pamięć podręczną pozwalają na poprawienie wydajności aplikacji sieciowej w tani i efektywny sposób.
Zapisanie mniej lub bardziej statycznych danych w pamięci podręcznej i serwowanie ich stamtąd, zamiast generować je od podstaw przy każdym
wywołaniu, pozwala na znaczne zaoszczędzenie czasu odpowiedzi aplikacji.
Zapisanie statycznych danych w pamięci podręcznej, zamiast generowania ich od podstaw przy każdym wywołaniu, pozwala na znaczne zaoszczędzenie czasu odpowiedzi aplikacji.
Zapis pamięci podręcznej może odbywać się na wielu poziomach i w wielu miejscach aplikacji. Po stronie serwera, na niskim poziomie,
można wykorzystać pamięć podręczną do zapisania podstawowych danych, takich jak zbiór informacji o najnowszych artykułach pobieranych z bazy danych.
@ -47,9 +47,19 @@ W tej sekcji przewodnika opiszemy sposób użycia Active Record dla baz relacyjn
## Deklarowanie klas Active Record <spanid="declaring-ar-classes"></span>
Na początek zadeklaruj klasę typu Active Record rozszerzając [[yii\db\ActiveRecord|ActiveRecord]]. Ponieważ każda klasa Active Record
jest powiązana z tabelą bazy danych, należy nadpisać metodę [[yii\db\ActiveRecord::tableName()|tableName()]], aby wskazać
odpowiednią tabelę.
Na początek zadeklaruj klasę typu Active Record rozszerzając [[yii\db\ActiveRecord|ActiveRecord]].
### Deklarowanie nazwy tabeli
Domyślnie każda klasa Active Record jest powiązana ze swoją tabelą w bazie danych.
Metoda [[yii\db\ActiveRecord::tableName()|tableName()]] zwraca nazwę tabeli konwertując nazwę klasy za pomocą [[yii\helpers\Inflector::camel2id()]].
Możesz przeciążyć tę metodę, jeśli tabela nie jest nazwana zgodnie z tą konwencją.
Identycznie zastosowany może być domyślny prefiks tabeli [[yii\db\Connection::$tablePrefix|tablePrefix]]. Przykładowo, jeśli
[[yii\db\Connection::$tablePrefix|tablePrefix]] to `tbl_`, tabelą klasy `Customer` staje się `tbl_customer`, a dla `OrderItem` jest to `tbl_order_item`.
Jeśli nazwa tabeli zostanie podana jako `{{%NazwaTabeli}}`, znak procent `%` zostanie zamieniony automatycznie na prefiks tabeli.
Dla przykładu, `{{%post}}` staje się `{{tbl_post}}`. Nawiasy wokół nazwy tabeli są używane dla odpowiedniego [podawania nazw w kwerendach SQL](db-dao.md#quoting-table-and-column-names).
W poniższym przykładzie deklarujemy klasę Active Record nazwaną `Customer` dla tabeli `customer` w bazie danych.
@ -68,11 +78,12 @@ class Customer extends ActiveRecord
*/
public static function tableName()
{
return 'customer';
return '{{customer}}';
}
}
```
### Aktywne rekordy nazywane są "modelami"
Instancje Active Record są traktowane jak [modele](structure-models.md). Z tego powodu zwykle dodajemy klasy Active Record
do przestrzeni nazw `app\models` (lub innej, przeznaczonej dla klas modeli).
Po wypełnieniu rezultatem kwerendy, [[yii\db\ActiveRecord]] przeprowadza automatyczne rzutowanie typów na wartościach swoich atrybutów,
używając do tego celu informacji zawartych w [schemacie tabeli bazy danych](db-dao.md#database-schema). Pozwala to na prawidłowe przedstawienie
danych pobranych z kolumny tabeli zadeklarowanej jako liczba całkowita, w postaci wartości typu PHP integer w instancji klasy ActiveRecord (typu boolean jako boolean itp.).
Mechanizm rzutowania ma jednak kilka ograniczeń:
* Wartości typu zmiennoprzecinkowego nie są konwertowane na float, a zamiast tego są przedstawiane jako łańcuch znaków, aby zachować dokładność ich liczbowej prezentacji.
* Konwersja typu integer zależy od zakresu liczb całkowitych używanego systemu operacyjnego.
Wartości kolumn zadeklarowanych jako 'unsigned integer' lub 'big integer' będą przekonwertowane do PHP integer tylko na systemach 64-bitowych,
a na 32-bitowych będą przedstawione jako łańcuchy znaków.
Zwróć uwagę na to, że rzutowanie typów jest wykonywane tylko podczas wypełniania instancji ActiveRecord rezultatem kwerendy. Automatyczna konwersja nie jest przeprowadzana
dla wartości załadowanych poprzez żądanie HTTP lub ustawionych bezpośrednio dla właściwości klasy.
Schemat tabeli będzie również użyty do przygotowania instrukcji SQL przy zapisywaniu danych ActiveRecord, aby upewnić się, że wartości są przypisane w kwerendzie z prawidłowymi typami.
Atrybuty instancji ActiveRecord nie będą jednak przekonwertowane w procesie zapisywania.
> Tip: możesz użyć [[yii\behaviors\AttributeTypecastBehavior]], aby skonfigurować proces rzutowania typów dla wartości atrybutów w momencie ich walidacji lub zapisu.
### Aktualizowanie wielu wierszy jednocześnie <spanid="updating-multiple-rows"></span>
Metody przedstawione powyżej działają na pojedynczych instancjach Active Record, dodając lub aktualizując indywidualne wiersze tabeli.
@ -575,9 +606,16 @@ try {
} catch(\Exception $e) {
$transaction->rollBack();
throw $e;
} catch(\Throwable $e) {
$transaction->rollBack();
throw $e;
}
```
> Note: w powyższym kodzie znajdują się dwa bloki catch dla kompatybilności
> z PHP 5.x i PHP 7.x. `\Exception` implementuje [interfejs `\Throwable`](http://php.net/manual/en/class.throwable.php)
> od PHP 7.0, zatem można pominąć część z `\Exception`, jeśli Twoja aplikacja używa tylko PHP 7.0 lub wyższego.
Drugi sposób polega na utworzeniu listy operacji bazodanowych, które wymagają transakcji za pomocą metody [[yii\db\ActiveRecord::transactions()|transactions()]].
Dla przykładu:
@ -961,7 +999,7 @@ W powyższym przykładzie modyfikujemy relacyjną kwerendę dodając warunek ze
Deklaracje relacji są zazwyczaj obustronne dla dwóch klas Active Record. Przykładowo `Customer` jest powiązany z `Order` poprzez relację `orders`,
@ -1253,10 +1301,10 @@ Domyślnie wszystkie kwerendy Active Record używają klasy [[yii\db\ActiveQuery
należy nadpisać metodę [[yii\db\ActiveRecord::find()|find()]], aby zwracała instancję żądanej klasy kwerend. Przykład:
```php
// plik Comment.php
namespace app\models;
use yii\db\ActiveRecord;
use yii\db\ActiveQuery;
class Comment extends ActiveRecord
{
@ -1265,33 +1313,39 @@ class Comment extends ActiveRecord
return new CommentQuery(get_called_class());
}
}
class CommentQuery extends ActiveQuery
{
// ...
}
```
Od tego momentu, za każdym razem, gdy wykonywana będzie kwerenda (np. `find()`, `findOne()`) lub pobierana relacja (np. `hasOne()`) klasy `Comment`,
praca będzie odbywać się na instancji `CommentQuery` zamiast `ActiveQuery`.
> Tip: Dla dużych projektów rekomendowane jest, aby używać własnych, odpowiednio dopasowanych do potrzeb, klas kwerend, dzięki czemu klasy Active Record
> pozostają przejrzyste.
Możesz dopasować klasę kwerend do własnych potrzeb na wiele kreatywnych sposobów. Przykładowo, możesz zdefiniować nowe metody konstruujące zapytanie:
Teraz należy zdefiniować klasę `CommentQuery`, którą można dopasować do własnych kreatywnych potrzeb, dzięki czemu budowanie zapytań bazodanowych będzie o wiele bardziej ułatwione. Dla przykładu,
```php
// plik CommentQuery.php
namespace app\models;
use yii\db\ActiveQuery;
class CommentQuery extends ActiveQuery
{
// dodatkowe warunki relacyjnej kwerendy dołączone jako domyślne (ten krok można pominąć)
public function init()
{
$this->andOnCondition(['deleted' => false]);
parent::init();
}
// ... dodaj zmodyfikowane metody kwerend w tym miejscu ...
> Note: Zwykle, zamiast wywoływać metodę [[yii\db\ActiveQuery::where()|where()]], powinno się używać metody
> [[yii\db\ActiveQuery::andWhere()|andWhere()]] lub [[yii\db\ActiveQuery::orWhere()|orWhere()]], aby dołączać kolejne warunki zapytania w
> Note: Zwykle, zamiast wywoływać metodę [[yii\db\ActiveQuery::onCondition()|onCondition()]], powinno się używać metody
> [[yii\db\ActiveQuery::andOnCondition()|andOnCondition()]] lub [[yii\db\ActiveQuery::orOnCondition()|orOnCondition()]], aby dołączać kolejne warunki zapytania w
> konstruktorze kwerend, dzięki czemu istniejące warunki nie zostaną nadpisane.
Powyższy przykład pozwala na użycie następującego kodu:
> Tip: Dla dużych projektów rekomendowane jest, aby używać własnych, odpowiednio dopasowanych do potrzeb, klas kwerend, dzięki czemu klasy Active Record
> pozostają przejrzyste.
Możesz także użyć nowych metod budowania kwerend przy definiowaniu relacji z `Comment` lub wykonywaniu relacyjnych kwerend:
```php
@ -1312,11 +1369,18 @@ class Customer extends \yii\db\ActiveRecord