Data Access Objects (DAO) tillhandahÄller ett generellt programmeringsgrÀnssnitt (API) för att ge tillgÄng till data lagrad i olika databahshanterare (DBMS). Detta medför att den underliggande databashanteraren kan bytas till en annan utan behov av Àndringar i den kod som anvÀnder DAO för dataÄtkomst.
Yii:s DAO har byggts ovanpÄ PHP Data Objects
(PDO)-tillÀgget, vilket tillhandahÄller
enhetlig Ätkomst till mÄnga populÀra databashanterare sÄsom MySQL, PostgreSQL.
Av denna anledning behöver PDO-tillÀgget och den databasspecifika PDO-
drivrutinen (t.ex. PDO_MYSQL) installeras innan Yii:s PDO anvÀnds.
Yii:s DAO bestÄr i huvudsak av följande fyra klasser:
I följande stycken introduceras anvÀndning av Yii:s DAO i olika scenarier.
För att upprÀtta en databasanslutning, skapa en instans av CDbConnection och aktivera den. Ett namn pÄ en datakÀlla (DSN) erfordras för att specificera nödvÀndig information för anslutning till databasen. Ett anvÀndarnamn och ett lösenord kan ocksÄ behövas för att upprÀtta anslutningen. En exception signaleras i hÀndelse av att ett fel uppstÄr under upprÀttandet av anslutningen (t.ex. felaktig DSN eller ogiltigt anvÀndarnamn/lösenord).
$connection=new CDbConnection($dsn,$username,$password);
// establish connection. You may try...catch possible exceptions
$connection->active=true;
......
$connection->active=false; // close connectionFormatet för ett DSN bestÀms av vilken databasspecifik PDO-drivrutin som anvÀnds. Generellt sett bestÄr ett DSN av namnet pÄ PDO-drivrutinen följt av ett kolon, följt av drivrutinsspecifik anslutningssyntax. Se PDO-dokumentationen för fullstÀndig information. Nedan Äterges en lista med vanligtvis anvÀnda DSN-format:
sqlite:/path/to/dbfilemysql:host=localhost;dbname=testdbpgsql:host=localhost;port=5432;dbname=testdbmssql:host=localhost;dbname=testdboci:dbname=//localhost:1521/testdbEftersom CDbConnection Àr en utvidgning av CApplicationComponent, kan vi
Àven anvÀnda den som just en
applikationskomponent.
För att göra sÄ, konfigurera in en db (eller annat namn) applikationskomponent i
applikationskonfigurationen
enligt följande,
array(
......
'components'=>array(
......
'db'=>array(
'class'=>'CDbConnection',
'connectionString'=>'mysql:host=localhost;dbname=testdb',
'username'=>'root',
'password'=>'password',
'emulatePrepare'=>true, // erfordras i vissa MySQL-installationer
),
),
)DÀrefter kan databasanslutningen tillgÄs via Yii::app()->db som redan Àr
automatiskt aktiverad, utom i det fall CDbConnection::autoConnect uttryckligen
konfigurerats till false. Med anvÀndande av detta tillvÀgagÄngssÀtt kan en enda
DB-anslutning delas av kod pÄ flera stÀllen.
NÀr en databasanslutning vÀl har etablerats, kan SQL-satser exekveras med hjÀlp av CDbCommand. Man skapar en instans av CDbCommand genom anrop till CDbConnection::createCommand() med SQL-satsen angiven:
$command=$connection->createCommand($sql);
// if needed, the SQL statement may be updated as follows:
// $command->text=$newSQL;En SQL-sats exekveras via CDbCommand pÄ ett av följande tvÄ sÀtt:
execute(): genomför en SQL-sats som inte returnerar
rader, sÄsom INSERT, UPDATE and DELETE. Vid felfritt genomförande
returneras antalet rader som omfattades av operationen.
query(): genomför en SQL-sats som returnerar rader av
data (eg. "pÄsar"), sÄsom SELECT. Vid felfritt genomförande, returneras en
instans av CDbDataReader frÄn vilken man kan traversera den resulterande
mÀngden av rader. För bekvÀmlighets skull har Àven en uppsÀttning
queryXXX()-metoder implementerats, vilka direkt returnerar respektive frÄgeresultat.
En exception signaleras om ett fel skulle intrÀffa under exekveringen av SQL-satser.
$rowCount=$command->execute(); // exekvera SQL som inte Àr en frÄga
$dataReader=$command->query(); // exekvera en SQL-frÄga
$rows=$command->queryAll(); // exekvera frÄga och returnera alla resultatrader
$row=$command->queryRow(); // exekvera frÄga och returnera första resultatraden
$column=$command->queryColumn(); // exekvera frÄga och returnera första resultatkolumnen
$value=$command->queryScalar(); // exekvera frÄga och returnera första fÀltet i första radenDÄ CDbCommand::query() genererat CDbDataReader-instansen, kan man hÀmta
resulterande datarader genom att repetitivt anropa CDbDataReader::read(). Man
kan Àven anvÀnda CDbDataReader i en i PHP-sprÄket tillgÀnglig foreach-sats
för att hÀmta data rad för rad.
$dataReader=$command->query();
// calling read() repeatedly until it returns false
while(($row=$dataReader->read())!==false) { ... }
// using foreach to traverse through every row of data
foreach($dataReader as $row) { ... }
// retrieving all rows at once in a single array
$rows=$dataReader->readAll();MÀrk: Till skillnad frÄn query(), returnerar alla
queryXXX()-metoder data direkt. Till exempel returnerar queryRow()|CDbCommand::queryRow] en array som representerar den första raden i frÄgeresultatet.
NÀr en applikation exekverar ett antal databasoperationer, som var och en lÀser information frÄn och/eller skriver information till databasen, Àr det viktigt att försÀkra sig om att databasen inte lÀmnas med nÄgra operationer ofullstÀndigt utförda. En transaktion, representerad i Yii som en instans av CDbTransaction, kan inledas för att sÀkerstÀlla detta:
OvanstÄende arbetsflöde kan implementeras med hjÀlp av följande kod:
$transaction=$connection->beginTransaction();
try
{
$connection->createCommand($sql1)->execute();
$connection->createCommand($sql2)->execute();
//.... other SQL executions
$transaction->commit();
}
catch(Exception $e) // an exception is raised if a query fails
{
$transaction->rollBack();
}För att undvika SQL- injekteringsattacker samt för förbÀttrad prestanda vid upprepad exekvering av SQL-satser, kan man i förekommande fall förbereda ("prepare") en SQL-sats med platsmarkörer för parametrar, som senare - vid koppling av parametrar (parameter binding) - kommer att ersÀttas med aktuella parametrar.
Parameterplatsmarkörerna kan antingen var namngivna (representerade av unika symboler) eller icke-namngivna (representerade av frÄgetecken). Anropa CDbCommand::bindParam() eller CDbCommand::bindValue() för att ersÀtta dessa platsmarkörer med de aktuella parametrarna. Parametrarna behöver inte omges av citationstecken; den underliggande databasdrivrutinen utför detta. Parameterkoppling mÄste ske innan SQL-satsen exekveras.
// an SQL with two placeholders ":username" and ":email"
$sql="INSERT INTO users(username, email) VALUES(:username,:email)";
$command=$connection->createCommand($sql);
// replace the placeholder ":username" with the actual username value
$command->bindParam(":username",$username,PDO::PARAM_STR);
// replace the placeholder ":email" with the actual email value
$command->bindParam(":email",$email,PDO::PARAM_STR);
$command->execute();
// insert another row with a new set of parameters
$command->bindParam(":username",$username2,PDO::PARAM_STR);
$command->bindParam(":email",$email2,PDO::PARAM_STR);
$command->execute();Metoderna bindParam() och bindValue() Àr mycket snarlika. Den enda skillnaden Àr att den förra kopplar en parameter till en PHP-variabelreferens, den senare med ett vÀrde. För parametrar som representerar stora block av dataminne Àr den förra metoden - av prestandaskÀl - att föredra.
För fler detaljer om parameterkoppling, se den tillÀmpliga PHP- dokumentationen.
Vid hÀmtning av frÄgeresultat kan man ocksÄ koppla kolumner till PHP-variabler sÄ att de automatiskt uppdateras med senaste data var gÄng en rad hÀmtas.
$sql="SELECT username, email FROM users";
$dataReader=$connection->createCommand($sql)->query();
// bind the 1st column (username) with the $username variable
$dataReader->bindColumn(1,$username);
// bind the 2nd column (email) with the $email variable
$dataReader->bindColumn(2,$email);
while($dataReader->read()!==false)
{
// $username and $email contain the username and email in the current row
}
Signup or Login in order to comment.