Data Access Objects (DAO)
Data Access Objects (DAO) dostarcza generycznego API umożliwiającego dostęp do danych przechowywanych w różnych systemach zarządzania bazą danych (ang. DBMS, pol. SZBD). W rezultacie, użyty SZBD może zostać zastąpiony przez inny bez potrzeby zmiany kodu używającego DAO aby uzyskać dostęp do danych.
Yii DAO zostało utworzone w oparciu o PHP Data Objects (PDO)
które jest rozszerzeniem dostarczającym ujednolicony dostęp do danych dla wielu
popularnych SZBD, takich jak MySQL, PostgreSQL. Dlatego też, by używać Yii DAO,
rozszerzenie PDO oraz poszczególne sterowniki PDO dla baz danych (np. PDO_MYSQL
)
muszą być zainstalowane.
Yii DAO składa się głównie z następujących czterech klas:
- CDbConnection: reprezentuje połączenie z bazą danych,
- CDbCommand: reprezentuje instrukcję SQL, wykonywaną dla bazy danych,
- CDbDataReader: reprezentuje przeglądany jedynie w przód strumień wierszy pochodzących z zestawu wyników zapytania,
- CDbTransaction: reprezentuje transakcję DB.
W dalszej części, przedstawimy użycie Yii DAO w różnych scenariuszach.
Ustanawianie połączenia z bazą danych
Aby ustanowić połączenie z bazą danych należy utworzyć instancję CDbConnection a następnie aktywować ją. Aby połączyć się z bazą danych potrzebny jest adres DNS. Użytkownik oraz hasło mogą być również potrzebne aby ustanowić połączenie. W przypadku gdy podczas łączenia nastąpi błąd (np. podano zły adres DNS lub złe hasło/nazwę użytkownika) zostanie rzucony odpowiedni wyjątek.
Format adresu DNS zależy od używanego, dla danej bazy danych, sterownika PDO. Uogólniając, DNS składa się z nazwy sterownika PDO, po którym następuje dwukropek a następnie zależna od sterownika składnia połączenia. Zobacz dokumentację PDO aby uzyskać więcej informacji. Poniżej znajduje się lista najczęściej używanych formatów DNS:
- SQLite:
sqlite:/scieżka/do/pliku/bazy
, - MySQL:
mysql:host=localhost;dbname=testdb
, - PostgreSQL:
pgsql:host=localhost;port=5432;dbname=testdb
, - SQL Server:
mssql:host=localhost;dbname=testdb
, - Oracle:
oci:dbname=//localhost:1521/testdb
Ponieważ klasa CDbConnection dziedziczy z klasy CApplicationComponent, możemy użyć jej jako komponent aplikacji. Aby to zrobić, należy skonfigurować komponent aplikacji 'db' (można użyć innej nazwy) w konfiguracji aplikacji w następujący sposób:
Dostęp do połączenia DB, można uzyskać poprzez Yii::app()->db
. Jest ono automatycznie
aktywowane, chyba że wyraźnie skonfigurujemy CDbConnection::autoConnect jako false.
Używając tego podejścia, jedno połączenie DB może być dzielone w wielu miejscach w naszym kodzie.
Wykonywanie instrukcji SQL
Gdy połączenie z bazą danych zostało ustanowione, można wykonywać instrukcje SQL za pomocą CDbCommand. Utworzenie instancji CDbCommand odbywa się poprzez wywołanie metody CDbConnection::createCommand() z określoną instrukcją SQL:
Instrukcja SQL może zostać wykonana za pomocą CDbCommand w jeden z dwóch poniższych sposobów:
execute(): wykonuje instrukcję SQL nie będącą zapytaniem taką jak
INSERT
,UPDATE
orazDELETE
. Jeśli wywołanie zakończy się sukcesem, metoda zwróci liczbę wierszy, na które wpłynęło wykonywanie instrukcji.query(): wykonuje instrukcję SQL, taką jak
SELECT
, która zwraca wiersze z danymi. Jeśli wywołanie zakończy się sukcesem, metoda zwróci instancję CDbDataReader, za pomocą której można przejrzeć wynikowe wiersze danych. Dla wygody został zaimplementowany zestaw metodqueryXXX()
, które to zwracają bezpośrednio wyniki zapytań.
Jeżeli podczas wykonywania indtrukcji SQL wystąpił błąd zostanie rzucony wyjątek.
Pobieranie wyników zapytań
Po wygenerowaniu przez metodę CDbCommand::query() instancji klasy CDbDataReader, można
zwrócić wiersze danych wynikowych poprzez powtarzanie wywoływania metody CDbDataReader::read().
Instancję CDbDataReader można używać w konstrukcji foreach
języka PHP co powoduje
dostęp do danych wiersz po wierszu.
Uwaga: W odróżnieniu od metody query(), wszystkie metody typu
queryXXX()
zwracają dane bezpośrednio. Na przykład, queryRow() zwraca tablicę reprezentującą pierwszy wiersz wyniku zapytań.
Używanie transakcji
Kiedy aplikacja wykonuje kilka zapytań, za każdym razem czytając i/lub zapisując informacje w bazie danych, ważnym jest by upewnić się, że na bazie danych nie została wykonana tylko część z tych zapytań. W takim przypadku może zostać zainicjowana transakcja reprezentowana w Yii poprzez instancję CDbTransaction:
- Rozpocznij transakcję.
- Wykonaj zapytania jedno po drugim. Żadna zmiana w bazie danych nie jest widoczna na zewnątrz.
- Potwierdź (commit) transakcję. Zmiany będą widoczne jeśli transakcja się powiedzie.
- Jeśli jedno z zapytań nie powiedzie się, cała transakcja zostanie anulowana (roll-back).
Powyższy logika może zostać zaimplementowana używając następującego kodu:
Przypinanie parametrów
Aby uniknąć ataków SQL injection oraz aby zwiększyć wydajność wykonywania często używanych instrukcji SQL, można "przygotować" instrukcję SQL z opcjonalnymi symbolami zastępczymi (ang. placeholders) parametrów, które to będą zastąpione przez aktualne parametry podczas procesu przypinania parametrów.
Symbole zastępcze parametrów mogą być zarówno nazwane (reprezentowane jako unikalne tokeny) lub mogą nie posiadać nazwy (reprezentowane za pomocą znaku zapytania). Aby zastąpić te symbole aktualnymi parametrami wywołaj metodę CDbCommand::bindParam() lub CDbCommand::bindValue(). Parametry te nie muszą być objęte cudzysłowem, użyty sterownik bazy danych zrobi to za Ciebie. Przypinanie parametrów musi nastąpić zanim instrukcja SQL zostanie wykonana.
Metody bindParam() oraz bindValue() są bardzo podobne. Jedyną różnicą jest to, że pierwsza przypina do parametru referencję zmiennej gdy druga wartość zmiennej. Dla parametrów które reprezentują duże bloki pamięci danych, pierwsza z nich jest korzystna ze względu na wydajność.
Aby uzyskać więcej informacji na temat przypinania parametrów zobacz odpowiednią dokumentację PHP.
Przypinanie kolumn
Podczas pobierania wyników zapytania, można również przypiąć do kolumny zmienne PHP tak, by były one automatycznie wypełniane najnowszymi danymi za każdym razem kiedy pobieramy wiersz.
Używanie prefiksów w tabelach
Yii dostarcza zintegrowanego wsparcia dla prefiksów tabel.
Prefiks tabeli to łańcuch znaków, który poprzedza nazwę tabel w bazie danych,
z którą jesteśmy połączeni. Prefiksów używa się najczęsciej we współdzielonych środowiku hostingowym,
gdzie wiele aplikacji dzieli jedną tabelę bazodanową i używa różnych prefiksów tabeli
w celu rozróżnienia ich od siebie. Na przykład, jedna aplikacja może używać prefiksu
tbl_
, druga zaś innego, np. yii_
.
Aby móc używać prefiksów tabel, należy przypisać właściwości CDbConnection::tablePrefix
pożądany prefiks tabeli. Następnie, w zapytaniach SQL należy używać konstrukcji {{TableName}}
,
gdzie TableName
wskazuje na nazwę tabeli bez prefiksu. Na przykład, jeśli baza danych zawiera
tabelę o nazwie tbl_user
, gdzie tbl_
zostało skonfigurowane jako prefiks tabeli,
wtedy możemy używać następującego kodu, aby zapytać o użytkowników: