mirror of
https://github.com/yiisoft/yii.git
synced 2026-03-06 16:16:53 +01:00
266 lines
10 KiB
Plaintext
266 lines
10 KiB
Plaintext
Data Access Objects (DAO)
|
|
========================
|
|
|
|
Data Access Objects (DAO) atau Objek Akses Data menyediakan API generik untuk mengakses data yang disimpan dalam
|
|
sistem manajemen database (DBMS) yang berbeda. Hasilnya, Lapisan DBMS
|
|
dapat diubah ke yang lain yang berbeda tanpa memerlukan perubahan kode
|
|
yang menggunakan DAO untuk mengakses data.
|
|
|
|
Yii DAO dibangun di atas [PHP Data Objects
|
|
(PDO)](http://php.net/manual/en/book.pdo.php) yang merupakan extension
|
|
yang menyediakan akses data gabungan untuk beberapa DBMS populer, seperti MySQL,
|
|
PostgreSQL. Oleh karena itu, untuk menggunakan Yii DAO, extension PDO dan driver database
|
|
PDO tertentu (misalnya `PDO_MYSQL`) harus sudah terinstal.
|
|
|
|
Yii DAO terdiri dari empat kelas utama sebagai berikut:
|
|
|
|
- [CDbConnection]: mewakili koneksi ke database.
|
|
- [CDbCommand]: mewakili pernyataan SQL untuk dijalankan pada database.
|
|
- [CDbDataReader]: mewakili forward-only stream terhadap baris dari set hasil queri.
|
|
- [CDbTransaction]: mewakili transaksi DB.
|
|
|
|
Berikutnya, kami memperkenalkan pemakaian Yii DAO dalam skenario
|
|
berbeda.
|
|
|
|
Membuat Koneksi Database
|
|
------------------------
|
|
|
|
Untuk membuat koneksi database, buat instance [CDbConnection] dan mengaktifkannya.
|
|
Nama sumber data (DSN) diperlukan untuk menetapkan informasi yang diperlukan
|
|
untuk menyambung ke database. Nama pengguna dan kata sandi juga diperlukan
|
|
guna melakukan koneksi. Exception akan dimunculkan seandainya kesalahan terjadi
|
|
selama pelaksanaan koneksi (misalnya DSN tidak benar atau username/password
|
|
tidak benar).
|
|
|
|
~~~
|
|
[php]
|
|
$connection=new CDbConnection($dsn,$username,$password);
|
|
// melakukan koneksi. Anda dapat mencoba try...catch exception yang mungkin
|
|
$connection->active=true;
|
|
......
|
|
$connection->active=false; // tutup koneksi
|
|
~~~
|
|
|
|
Format DSN tergantung pada driver PDO database yang digunakan. Secara umum, DSN
|
|
terdiri dari nama driver PDO, diikuti oleh titik dua, diikuti oleh
|
|
sintaks koneksi spesifik-driver. Lihat [Dokumentasi
|
|
PDO](http://www.php.net/manual/en/pdo.construct.php) untuk informasi
|
|
lebih lengkap. Di bawah ini adalah daftar format DSN yang umum dipakai:
|
|
|
|
- SQLite: `sqlite:/path/to/dbfile`
|
|
- 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`
|
|
|
|
Karena [CDbConnection] diturunkan dari [CApplicationComponent], kita juga dapat
|
|
menggunakannya sebagai [komponen
|
|
aplikasi](/doc/guide/basics.application#application-component). Untuk melakukannya, konfigurasi
|
|
dalam komponen aplikasi `db` (atau nama lain) pada [konfigurasi
|
|
aplikasi](/doc/guide/basics.application#application-configuration) sebagai berikut,
|
|
|
|
~~~
|
|
[php]
|
|
array(
|
|
......
|
|
'components'=>array(
|
|
......
|
|
'db'=>array(
|
|
'class'=>'CDbConnection',
|
|
'connectionString'=>'mysql:host=localhost;dbname=testdb',
|
|
'username'=>'root',
|
|
'password'=>'password',
|
|
'emulatePrepare'=>true, // pada beberapa instalasi MySQL, diperlukan
|
|
),
|
|
),
|
|
)
|
|
~~~
|
|
|
|
Selanjutnya kita dapat mengakses koneksi DB via `Yii::app()->db` yang sudah
|
|
diaktifkan secara otomatis, kecuali dikonfigurasi secara eksplisit
|
|
[CDbConnection::autoConnect] menjadi false. Menggunakan pendekatan ini, koneksi DB
|
|
tunggal dapat dibagi dalam tempat multipel pada kode kita.
|
|
|
|
Menjalankan Pernyataan SQL
|
|
--------------------------
|
|
|
|
Setelah koneksi database terlaksana, pernyataan SQL dapat dijalankan
|
|
menggunakan [CDbCommand]. Membuat instance [CDbCommand] dengan memanggil
|
|
[CDbConnection::createCommand()] dengan pernyataan SQL yang ditetapkan:
|
|
|
|
~~~
|
|
[php]
|
|
$connection=Yii::app()->db; // asumsi bahwa anda memiliki koneksi "db" yang terkonfigurasi
|
|
// Jika tidak, anda bisa membuat sebuah koneksi secara eksplisit
|
|
// $connection=new CDbConnection($dsn,$username,$password);
|
|
$command=$connection->createCommand($sql);
|
|
// jika diperlukan, statement SQL dapat diupdate sebagai berikut
|
|
// $command->text=$newSQL;
|
|
~~~
|
|
|
|
Pernyataan SQL dijalankan via [CDbCommand] dalam dua cara
|
|
berikut:
|
|
|
|
- [execute()|CDbCommand::execute]: melakukan pernyataan SQL non-queri,
|
|
seperti `INSERT`, `UPDATE` and `DELETE`. Jika berhasil, mengembalikan
|
|
sejumlah baris yang dipengaruhi oleh eksekusi
|
|
|
|
- [query()|CDbCommand::query]: melakukan pernyataan SQL yang mengembalikan
|
|
baris data, seperti `SELECT`. Jika berhasil,mengembalikan instance [CDbDataReader]
|
|
yang dapat ditelusuri baris data yang dihasilkan. Untuk
|
|
kenyamanan, satu set metode `queryXXX()` juga diimplementasikan yang secara
|
|
langsung mengembalikan hasil queri.
|
|
|
|
Exception akan dimunculkan jika kesalahan terjadi selama eksekusi pernyataan
|
|
SQL.
|
|
|
|
~~~
|
|
[php]
|
|
$rowCount=$command->execute(); // jalankan SQL non-queri
|
|
$dataReader=$command->query(); // jalankan queri SQL
|
|
$rows=$command->queryAll(); // queri dan kembalikan seluruh baris hasil
|
|
$row=$command->queryRow(); // query dan kembalikan baris pertama hasil
|
|
$column=$command->queryColumn(); // query dan kembalikan kolom pertama hasil
|
|
$value=$command->queryScalar(); // query dan kembalikan field pertama dalam baris pertama
|
|
~~~
|
|
|
|
Mengambil Hasil Queri
|
|
---------------------
|
|
|
|
Setelah [CDbCommand::query()] membuat instance [CDbDataReader], Anda
|
|
bisa mengambil baris data yang dihasilkan oleh pemanggilan [CDbDataReader::read()]
|
|
secara berulang. Ia juga dapat menggunakan [CDbDataReader] dalam konsrruksi bahasa PHP
|
|
`foreach` untuk mengambil baris demi baris.
|
|
|
|
~~~
|
|
[php]
|
|
$dataReader=$command->query();
|
|
// memanggil read() secara terus menerus sampai ia mengembalikan false
|
|
while(($row=$dataReader->read())!==false) { ... }
|
|
// menggunakan foreach untuk menelusuri setiap baris data
|
|
foreach($dataReader as $row) { ... }
|
|
// mengambil seluruh baris sekaligus dalam satu array tunggal
|
|
$rows=$dataReader->readAll();
|
|
~~~
|
|
|
|
> Note|Catatan: Tidak seperti [query()|CDbCommand::query], semua metode `queryXXX()`
|
|
mengembalikan data secara langsung. Sebagai contoh, [queryRow()|CDbCommand::queryRow]
|
|
mengembalikan array yang mewakili baris pertama pada hasil queri.
|
|
|
|
Menggunakan Transaksi
|
|
---------------------
|
|
|
|
Ketika aplikasi menjalankan beberapa queri, setiap pembacaan dan/atau penulisan
|
|
informasi dalam database, penting untuk memastikan bahwa database tidak
|
|
tertinggal dengan hanya beberapa queri yang dihasilkan. Transaksi diwakili
|
|
oleh instance [CDbTransaction] dalam Yii, dapat diinisiasi dalam
|
|
hal:
|
|
|
|
- Mulai transaksi.
|
|
- Jalankan queri satu demi satu. Setiap pemutakhiran pada database tidak terlihat bagi dunia luar.
|
|
- Lakukan transaksi. Pemutakhiran menjadi terlihat jika transaksi berhasil.
|
|
- Jika salah satu queri gagal, seluruh transaksi dibatalkan.
|
|
|
|
Alur kerja di atas dapat diimplementasikan menggunakan kode berikut:
|
|
|
|
~~~
|
|
[php]
|
|
$transaction=$connection->beginTransaction();
|
|
try
|
|
{
|
|
$connection->createCommand($sql1)->execute();
|
|
$connection->createCommand($sql2)->execute();
|
|
//.... eksekusi SQL lainnya
|
|
$transaction->commit();
|
|
}
|
|
catch(Exception $e) // exception dimunculkan jika queri gagal
|
|
{
|
|
$transaction->rollBack();
|
|
}
|
|
~~~
|
|
|
|
Mengikat Parameter
|
|
------------------
|
|
|
|
Untuk menghindari [serangan injeksi
|
|
SQL](http://en.wikipedia.org/wiki/SQL_injection) dan meningkatkan
|
|
kinerja pelaksanaan pernyataan SQL secara terus menerus, Anda dapat "menyiapkan"
|
|
sebuah pernyataan SQL dengan opsional penampung parameter yang akan
|
|
diganti dengan parameter sebenarnya selama proses pengikatan parameter.
|
|
|
|
Penampung parameter dapat bernama (disajikan sebagai token
|
|
unik) ataupun tidak bernama (disajikan sebagai tanda tanya). Panggil
|
|
[CDbCommand::bindParam()] atau [CDbCommand::bindValue()] untuk mengganti penampung
|
|
ini dengan parameter sebenarnya. Parameter tidak harus bertanda
|
|
kutip: lapisan driver database melakukan ini bagi Anda. Pengikatan parameter
|
|
harus dikerjakan sebelum pernyataan SQL dijalankan.
|
|
|
|
~~~
|
|
[php]
|
|
// SQL dengan dua penampung ":username" and ":email"
|
|
$sql="INSERT INTO tbl_user (username, email) VALUES(:username,:email)";
|
|
$command=$connection->createCommand($sql);
|
|
// ganti penampung ":username" dengan nilai username sebenarnya
|
|
$command->bindParam(":username",$username,PDO::PARAM_STR);
|
|
// ganti penampung ":email" dengan nilai email sebenarnya
|
|
$command->bindParam(":email",$email,PDO::PARAM_STR);
|
|
$command->execute();
|
|
// sisipkan baris lain dengan set baru parameter
|
|
$command->bindParam(":username",$username2,PDO::PARAM_STR);
|
|
$command->bindParam(":email",$email2,PDO::PARAM_STR);
|
|
$command->execute();
|
|
~~~
|
|
|
|
Metode [bindParam()|CDbCommand::bindParam] dan
|
|
[bindValue()|CDbCommand::bindValue] sangat mirip. Perbedaannya hanyalah bahwa
|
|
bidParam mengikat parameter dengan referensi variabel PHP sedangkan
|
|
bindValue dengan nilai. Untuk parameter yang mewakili memori blok besar data,
|
|
bindParam dipilih dengan pertimbangan kinerja.
|
|
|
|
Untuk lebih jelasnya mengenai pengikatan parameter, lihat [dokumentasi PHP
|
|
relevan](http://www.php.net/manual/en/pdostatement.bindparam.php).
|
|
|
|
Mengikat Kolom
|
|
--------------
|
|
|
|
Ketika mengambil hasil queri, Anda dapat mengikat kolom ke variabel PHP
|
|
dengan demikian hasil akan dipopulasi secara otomatis dengan data terbaru setiap kali
|
|
baris diambil.
|
|
|
|
~~~
|
|
[php]
|
|
$sql="SELECT username, email FROM tbl_user";
|
|
$dataReader=$connection->createCommand($sql)->query();
|
|
// ikat kolom ke-1 (username) ke variabel $username
|
|
$dataReader->bindColumn(1,$username);
|
|
// ikat kolom ke-2 (email) ke variabel $email
|
|
$dataReader->bindColumn(2,$email);
|
|
while($dataReader->read()!==false)
|
|
{
|
|
// $username dan $email berisi username dan email pada baris saat ini
|
|
}
|
|
~~~
|
|
|
|
Menggunakan Prefiks Tabel
|
|
------------------
|
|
|
|
Mulai dari versi 1.1.0, Yii menyediakan dukungan terintegrasi untuk menggunakan
|
|
prefiks tabel. Prefiks tabel merupakan sebuah string yang dipasang di depan nama
|
|
tabel yang sedang terkoneksi ke database. Kebanyakan digunakan pada lingkungan
|
|
shared-hosting yang mana berbagai aplikasi saling pakai sebuah database dan menggunakan
|
|
prefiks tabel yang berbeda untuk saling membedakan. Misalnya, satu aplikasi bisa
|
|
menggunakan `tbl_` sebagai prefiks sedangkan aplikasi yang lain bisa saja menggunakan `yii_`
|
|
|
|
Untuk menggunakan prefiks tabel, mengkonfigurasi properti [CdbConnection::tablePrefix] menjadi
|
|
sesuai dengan prefiks tabel yang diinginkan. Kemudia, dalam statement SQL gunakan `{{NamaTabel}}`
|
|
untuk merujuk nama tabel, di mana `NamaTabel` adalah nama table tanpa prefik.
|
|
Misalnya, jika database terdapat sebuah tabel bernama `tbl_user`
|
|
di mana `tbl_` dikonfigurasi sebagai prefiks tabel, maka kita dapat menggunakan kode berikut untuk query user.
|
|
|
|
~~~
|
|
[php]
|
|
$sql='SELECT * FROM {{user}}';
|
|
$users=$connection->createCommand($sql)->queryAll();
|
|
~~~
|
|
|
|
<div class="revision">$Id: database.dao.txt 2266 2010-07-17 13:58:30Z qiang.xue $</div> |