0

0

0

share


#php#yii2
0 Reaksi

0 Komentar

Memulai Pembuatan Aplikasi Web dengan Yii2 (5): Terhubung Ke Database

Profile

Muhammad Arslan8 Juli 2016

Salah satu menu utama yang harus tersedia dalam sebuah web framework adalah dapat mengakses database. Umumnya database yang dapat diakses adalah relational database management system (RDBMS) yang dapat digunakan seperti MySQL, MariaDB, PostgreSQL, dan SQLite3. Ada juga beberapa web framework yang dapat mengakses RDBMS lainnya seperti Oracle, Microsoft SQL Server, Ingress, dan lainnya. Yii2 sendiri mendukung database non relasional seperti MongoDB, Redis, dan ElasticSearch. Yii2 menyediakan API untuk mengakses ketiga database non relasional tersebut yang tertuang di dokumentasi resmi Yii2.

Kali ini, kita akan mencoba menggunakan mengakses database MySQL dengan melakukan query select, insert, update, delete, dan beberapa agregasi sederhana yang dilakukan dengan menggunakan query builder dan active record di Yii2. Keduanya merupakan fitur Andalan Yii2, dalam mengolah tabel yang akan Anda buat di MySQL. Selain itu kita akan mencoba juga konfigurasi sederhana yang dapat dilakukan untuk mengakses database MySQL.

Persiapan Coding

Anda dapat menggunakan source code hello-yii yang ada di tutorial seri "Memulai Pembuatan Aplikasi Web dengan Yii2" untuk digunakan di tutorial ini. Sehingga Anda tidak perlu membuat dari source code baru. Kemudian silahkan buat database baru di MySQL dengan nama soccerdb. Anda dapat melakukannya dengan menggunakan PHPMyAdmin, Console, ataupun JSQLBeans untuk membuat database tersebut.

Sekarang silahkan jalankan query berikut di salah satu aplikasi client database tersebut:

CREATE TABLE IF NOT EXISTS `teams` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `country` varchar(50) NOT NULL,
  `description` text NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `name_idx` (`name`) USING BTREE
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='Tabel untuk menyimpan data tim sepakbola' AUTO_INCREMENT=11 ;

INSERT INTO `teams` (`id`, `name`, `country`, `description`) VALUES
(1, 'Persib Bandung', 'Indonesia', 'Berada di Bandung'),
(2, 'Manchester United FC', 'England', 'Lorem ipsum sit dolor amet'),
(3, 'Liverpool FC', 'England', 'lorem ipsum sit dolor amet'),
(4, 'Bayern Muenchen', 'Germany', 'lorem ipsum sit dolor amet'),
(5, 'Paris Saint German', 'France', 'lorem ipsum sit dolor amet'),
(6, 'Arema Cronus', 'Indonesia', 'Tim dari jawa timur'),
(7, 'Persipura Jayapura', 'Indonesia', 'tim dari papua disebut juga dengan mutiara hitam'),
(8, 'Bali United FC', 'Indonesia', 'Tim dari bali yang punya sebutan serdadu tridatu'),
(9, 'Semen Padang FC', 'Indonesia', 'Tim dari Sumatera Barat ini punya sebutan kabau sirah'),
(10, 'Guangzhou Evergrande', 'China', 'Juara champion asia waktu tahun 2015');

Pada source code diatas kita membuat sebuah tabel dengan nama teams yang memiliki empat field yaitu id, name, country, dan description. Kemudian kita tambahkan 10 data dummy untuk digunakan dalam segmen query select di tutorial ini.

Konfigurasi Database Minimal di Yii2

Beberapa informasi yang dibutuhkan oleh Yii2 untuk mengakses database MySQL adalah nama dari database, username, dan password untuk mengakses database. Berikut adalah contoh konfigurasi yang diperlukan untuk mengakses database soccerdb:
<?php

return [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=soccerdb', 'username' => 'root', 'password' => 'root', 'charset' => 'utf8', ];

Password dan username pada konfigurasi diatas tentunya berbeda - beda di database yang Anda install. Sesuaikan username dan password database yang telah Anda install di laptop atau komputer Anda. Biasanya jika MySQL dipasang di Windows, password biasanya diabaikan dan tidak perlu Anda isi.

Menggunakan Query Select dengan Query Builder

Sekarang kita akan mencoba terlebih dahulu melakukan query ke database dengan menggunakan query builder. Sekarang silahkan buat terlebih dahulu file dengan nama HelloDatabaseController.php di folder controllers. Kemudian buat controller HelloDatabaseController di file tersebut. Kita akan mengawalinya dengan membuat sebuah action dengan nama actionIndex(). Di dalam action tersebut akan terdapat 5 variasi query select dengan menggunakan query builder.
<?php

namespace app\controllers;

use Yii; use yii\filters\AccessControl; use yii\web\Controller;

class HelloDatabaseController extends Controller { public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', ], ]; }

public function actionIndex()
{
    $query1 = (new \yii\db\Query())
                -&gt;select(['*'])
                -&gt;from('teams')
                -&gt;all();

    $query2 = (new \yii\db\Query())
                -&gt;select(['id', 'name', 'country'])
                -&gt;from('teams')
                -&gt;limit(5)
                -&gt;all();

    $query3 = (new \yii\db\Query())
                -&gt;select(['*'])
                -&gt;from('teams')
                -&gt;where(['country' =&gt; 'England'])
                -&gt;orderBy('name')
                -&gt;all();

    $query4 = (new \yii\db\Query())
                -&gt;select(['*'])
                -&gt;from('teams')
                -&gt;where(['like', 'description', 'sebut'])
                -&gt;orderBy('name')
                -&gt;all();

    $query5 = (new \yii\db\Query())
                -&gt;select(['country', 'count(country) as "total"'])
                -&gt;from('teams')
                -&gt;groupBy('country')
                -&gt;orderBy(['total' =&gt; SORT_DESC])
                -&gt;all();

    return $this-&gt;render('query-builder-index', [
                                                    'query1'=&gt;$query1, 
                                                    'query2'=&gt;$query2,
                                                    'query3'=&gt;$query3,
                                                    'query4'=&gt;$query4,
                                                    'query5'=&gt;$query5,
                                                ]);
}

}

Sekarang mari kita perhatikan satu per satu query builder diatas:

  • query1, kita melakukan query terhadap tabel teams dengan mengambil semua field dan semua baris. Tanda asterisk atau bintang pada function select() menandakan bahwa semua field yang ada akan diambil. Ada dua opsi untuk mengeluarkan baris data dari tabel. Bila all() maka semuanya akan dikeluarkan, bila one() maka akan cuma dikeluarkan satu saja
  • query2, kita hanya mengambil field id, name, dan country. Kemudian kita hanya batasi lima baris data saja yang dikeluarkan dari tabel
  • query3, kita ambil semua field dan disaring yang hanya berasal dari country dengan nilai "England". Kemudian kita urutkan dengan field name
  • query4, hampir sama dengan query3, hanya saja kita melakukan operator like untuk mencari potongan "sebut" di dalam field description. Sehingga hanya baris yang mengandung kata "sebut" yang akan dikeluarkan
  • query5, kita coba lakukan agregasi sederhana dengan menghitung banyaknya tim berdasarkan country. Kita gunakan operator agregasi count() yang terdapat di MySQL. Kemudian dikelompokkan dengan field country. Kemudian diurutkan dengan menggunakan field alias "total" secara menurun. Sehingga hasil terbanyak akan muncul di baris paling awal.
Terakhir kita lewatkan hasil query diatas ke dalam view query-builder-index.php. File view tersebut harus Anda buat di dalam folder views/hello-database. Kemudian buat file baru dengan nama query-builder-index.php, dan buat kode berikut di dalam file tersebut:
<?php 

$this->title = 'Demo Query Builder Yii2';

?>

<h1>Daftar Tim Sepak Bola</h1>

<p>Data berikut diambil dengan menggunakan query builder:</p> <pre> $query1 = (new \yii\db\Query()) ->select(['*']) ->from('teams') ->all(); </pre> <p>==> return <?= count($query1) ?> rows</p> <table class="table table-bordered table-striped"> <thead> <tr> <td>ID</td> <td>Name</td> <td>Country</td> <td>Description</td> </tr> </thead> <tbody> <?php foreach ($query1 as $team): ?> <tr> <td><?= $team['id'] ?></td> <td><?= $team['name'] ?></td> <td><?= $team['country'] ?></td> <td><?= $team['description'] ?></td> </tr> <?php endforeach; ?> </tbody> </table>

<hr /> <pre> $query2 = (new \yii\db\Query()) ->select(['id', 'name', 'country']) ->from('teams') ->limit(5) ->all(); </pre> <p>==> return <?= count($query2) ?> rows</p> <table class="table table-bordered table-striped"> <thead> <tr> <td>ID</td> <td>Name</td> <td>Country</td> </tr> </thead> <tbody> <?php foreach ($query2 as $team): ?> <tr> <td><?= $team['id'] ?></td> <td><?= $team['name'] ?></td> <td><?= $team['country'] ?></td> </tr> <?php endforeach; ?> </tbody> </table>

<hr /> <pre> $query3 = (new \yii\db\Query()) ->select(['*']) ->from('teams') ->where(['country' => 'England']) ->orderBy('name') ->all(); </pre> <p>==> return <?= count($query3) ?> rows</p> <table class="table table-bordered table-striped"> <thead> <tr> <td>ID</td> <td>Name</td> <td>Country</td> <td>Description</td> </tr> </thead> <tbody> <?php foreach ($query3 as $team): ?> <tr> <td><?= $team['id'] ?></td> <td><?= $team['name'] ?></td> <td><?= $team['country'] ?></td> <td><?= $team['description'] ?></td> </tr> <?php endforeach; ?> </tbody> </table>

<hr /> <pre> $query4 = (new \yii\db\Query()) ->select(['*']) ->from('teams') ->where(['description' => '%sebut%']) ->orderBy('name') ->all(); </pre> <p>==> return <?= count($query4) ?> rows</p> <table class="table table-bordered table-striped"> <thead> <tr> <td>ID</td> <td>Name</td> <td>Country</td> <td>Description</td> </tr> </thead> <tbody> <?php foreach ($query4 as $team): ?> <tr> <td><?= $team['id'] ?></td> <td><?= $team['name'] ?></td> <td><?= $team['country'] ?></td> <td><?= $team['description'] ?></td> </tr> <?php endforeach; ?> </tbody> </table>

<hr /> <pre> $query5 = (new \yii\db\Query()) ->select(['country']) ->from('teams') ->groupBy('country') ->orderBy('name') ->all(); </pre> <p>==> return <?= count($query5) ?> rows</p> <table class="table table-bordered table-striped"> <thead> <tr> <td>Country</td> <td>Total</td> </tr> </thead> <tbody> <?php foreach ($query5 as $team): ?> <tr> <td><?= $team['country'] ?></td> <td><?= $team['total'] ?></td> </tr> <?php endforeach; ?> </tbody> </table>

Sekarang mari kita lihat hasilnya dengan mengakses URL http://localhost/hello-yii/web/index.php?r=hello-database:

Selection_013 Selection_014 Selection_015 Selection_016 Selection_017

Menggunakan Query Select dengan Active Record

Dalam melakukan query select, active record tidak berbeda jauh dengan query builder. Hanya saja active record digunakan apabila Anda ingin melakukan operasi seperti update, insert, delete, dan join yang lebih mudah dengan menggunakan relasi antar class active record. Tidak seperti query builder yang dapat Anda tulis tanpa membuat file yang merepresentasikan sebuah tabel, active record mengharuskan Anda untuk membuat sebuah class yang mewarisi yii\db\ActiveRecord untuk digunakan pada operasi - operasi yang telah disebutkan.

Karena kita hanya membuat sebuah tabel yaitu teams. Maka kita samakan saja nama file dan class ActiveRecord tersebut. Buatlah sebuah file dengan nama Teams.php di folder models, kemudian buat class berikut di dalam file tersebut:

<?php

namespace app\models;

use yii\db\ActiveRecord;

class Teams extends ActiveRecord
{
    public $teamsCount;

    public static function tableName()
    {
        return 'teams';
    }
}

Pada kode diatas, ada dua hal yang perlu Anda perhatikan. Atribut $teamsCount akan digunakan saat agregasi yang akan berfungsi sebagai penampung hasil agregasi. Sedangkan function tableName() adalah function yang wajib Anda tulis untuk menentukan tabel mana yang akan dibaca oleh class active record. Setelah membuat class tersebut, Anda dapat menggunakan class tersebut di controllers. Anda dapat menambahkannya dengan memanggil use app\models\Teams; di dalam HelloDatabaseController.php. Kemudian silahkan buat action baru dengan nama actionDemoActiveQueryIndex() yang akan berisi kode untuk menampilkan hasil query dari active record:

<?php

namespace app\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use app\models\Teams;

class HelloDatabaseController extends Controller
{
    ...............

    public function actionDemoActiveQueryIndex()
    {
        $query1 = Teams::find()->all();

        $query2 = Teams::find()->select(['id', 'name', 'country'])->limit(7)->all();

        $query3 = Teams::find()
                        ->where(['country' => 'Indonesia'])
                        ->orderBy('name')
                        ->all();

        $query4 = Teams::find()
                    ->where(['like', 'description', 'dolor'])
                    ->orderBy('name')
                    ->all();

        $query5 = Teams::find()
                    ->select(['country', 'COUNT(country) as teamsCount'])
                    ->groupBy('country')
                    ->orderBy(['teamsCount' => SORT_DESC])
                    ->all();

        return $this->render('activerecord-index', [
                                                        'query1'=>$query1, 
                                                        'query2'=>$query2,
                                                        'query3'=>$query3,
                                                        'query4'=>$query4,
                                                        'query5'=>$query5,
                                                    ]);
    }
}

Dapat Anda perhatikan pada kode diatas, bahwa yang berbeda hanya bagian awalnya saja yaitu (new \yii\db\Query()) diganti menjadi Teams::find(). Kemudian hal yang berbeda lainnya adalah ketika Anda melakukan agregasi di $query5. Anda harus memanggil $teamsCount di dalam query agar hasil agregasi dapat disimpan dan dibaca di view. Sekarang untuk menampilkan hasilnya, silahkan buat sebuah view di folder views dengan nama active-record-index.php kemudian buat kode berikut di dalam file tersebut:

<?php 

$this->title = 'Demo Active Record Yii2';

?>

<h1>Daftar Tim Sepak Bola</h1>

<p>Data berikut diambil dengan menggunakan query builder:</p>
<pre>
$query1 = Teams::find()->all();
</pre>
<p>==> return <?= count($query1) ?> rows</p>
<table class="table table-bordered table-striped">
    <thead>
        <tr>
            <td>ID</td>
            <td>Name</td>
            <td>Country</td>
            <td>Description</td>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($query1 as $team): ?>
            <tr>
                <td><?= $team['id'] ?></td>
                <td><?= $team['name'] ?></td>
                <td><?= $team['country'] ?></td>
                <td><?= $team['description'] ?></td>
            </tr>
        <?php endforeach; ?>
    </tbody>
</table>

<hr />
<pre>
 $query2 = Teams::find()->select('id', 'name', 'country')->limit(7)->all();
</pre>
<p>==> return <?= count($query2) ?> rows</p>
<table class="table table-bordered table-striped">
    <thead>
        <tr>
            <td>ID</td>
            <td>Name</td>
            <td>Country</td>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($query2 as $team): ?>
            <tr>
                <td><?= $team['id'] ?></td>
                <td><?= $team['name'] ?></td>
                <td><?= $team['country'] ?></td>
            </tr>
        <?php endforeach; ?>
    </tbody>
</table>

<hr />
<pre>
$query3 = Teams::find()
                ->where(['country' => 'Indonesia'])
                ->orderBy('name')
                ->all();
</pre>
<p>==> return <?= count($query3) ?> rows</p>
<table class="table table-bordered table-striped">
    <thead>
        <tr>
            <td>ID</td>
            <td>Name</td>
            <td>Country</td>
            <td>Description</td>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($query3 as $team): ?>
            <tr>
                <td><?= $team['id'] ?></td>
                <td><?= $team['name'] ?></td>
                <td><?= $team['country'] ?></td>
                <td><?= $team['description'] ?></td>
            </tr>
        <?php endforeach; ?>
    </tbody>
</table>

<hr />
<pre>
$query4 = Teams::find()
                    ->where(['like', 'description', 'dolor'])
                    ->orderBy('name')
                    ->all();
</pre>
<p>==> return <?= count($query4) ?> rows</p>
<table class="table table-bordered table-striped">
    <thead>
        <tr>
            <td>ID</td>
            <td>Name</td>
            <td>Country</td>
            <td>Description</td>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($query4 as $team): ?>
            <tr>
                <td><?= $team['id'] ?></td>
                <td><?= $team['name'] ?></td>
                <td><?= $team['country'] ?></td>
                <td><?= $team['description'] ?></td>
            </tr>
        <?php endforeach; ?>
    </tbody>
</table>

<hr />
<pre>
$query5 = Teams::find()
                    ->select(['country', 'COUNT(country) as teamsCount'])
                    ->groupBy('country')
                    ->orderBy(['teamsCount' => SORT_DESC])
                    ->all();
</pre>
<p>==> return <?= count($query5) ?> rows</p>
<table class="table table-bordered table-striped">
    <thead>
        <tr>
            <td>Country</td>
            <td>Total</td>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($query5 as $team): ?>
            <tr>
                <td><?= $team['country'] ?></td>
                <td><?= $team['teamsCount'] ?></td>
            </tr>
        <?php endforeach; ?>
    </tbody>
</table>

Perbedaannya hanya di bagian kelima saja, Anda memanggil $team['teamsCount'] untuk mengeluarkan hasil dari hasil agregasi. Sekarang mari coba akses hasil pekerjaan kita melalui URL http://localhost/hello-yii/web/index.php?r=hello-database/demo-active-query-index:

Selection_008 Selection_009 Selection_010 Selection_011 Selection_012

Menambah Data Baru dengan Active Record

Cukup banyak yah query select yang telah kita coba. Sekarang saatnya kita mencoba menambahkan data baru di tabel teams dengan menggunakan active record. Cukup mudah untuk menambahkan data baru ke suatu tabel dengan menggunakan active record. Pertama, Anda harus meng-import terlebih dahulu class active record yang akan digunakan. Kemudian Anda harus membuat sebuah instance atau objek dari class tersebut. Misal pada kode dibawah ini kita membuat sebuah variabel dengan nama $teams kemudian kita buat objek dari class Teams dengan menggunakan operator new.

Lalu setelah itu kita isi nilai setiap field yang akan diberi nilai yaitu name, country, dan description. Kemudian panggil method save() untuk menyimpannya. field id tidak diisi karena sudah dibuat menjadi auto increment, sehingga dapat dilewat. Kemudian kita panggil view message.php untuk memperlihatkan bahwa tidak ada error saat mengeksekusi action tersebut:

<?php

namespace app\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use app\models\Teams;

class HelloDatabaseController extends Controller
{
    ...............

    public function actionDemoActiveQueryCreate()
    {
        $teams = new Teams();
        $teams->name = 'Real Madrid FC';
        $teams->country = 'Spain';
        $teams->description = 'Lorem ipsum sit dolor amet';
        $teams->save();

        return $this->render('message', ['method'=>__METHOD__]);
    }
}

Karena view message.php belum dibuat, maka buatlah dahulu di folder views kemudian buat kode berikut:

<h1>Demo Akses Database di Yii2</h1>

<p>Action <b><?= $method ?></b> telah dijalankan...</p>

Sekarang mari kita lihat hasilnya dengan mengeksekusi URL http://localhost/hello-yii/web/index.php?r=hello-database/demo-active-query-create:

Selection_006 Selection_001

Mengubah Data dengan Active Record

Sedikit berbeda dengan kode untuk menambah data, variabel $teams diisi dengan hasil query Teams::findOne(11), dimana kita mengambil sebuah baris data dengan id 11 di tabel teams. Hasil kembalianya tersebut dapat kita ubah sesuai kehendak kita. Pada kode dibawah kita ubah nama "Real Madrid FC" menjadi "Real Madrid Football Club", begitu juga kita ubah isi dari field description. Setelah itu kita simpan kembali data yang telah kita ubah, dan secara otomatis akan meng-update baris data dengan id 11.
<?php

namespace app\controllers;

use Yii; use yii\filters\AccessControl; use yii\web\Controller; use app\models\Teams;

class HelloDatabaseController extends Controller { ...............

public function actionDemoActiveQueryEdit()
{
    $teams = Teams::findOne(11);
    $teams-&gt;name = 'Real Madrid Football Club';
    $teams-&gt;description = 'One of the most popular football club in the world';
    $teams-&gt;save();

    return $this-&gt;render('message', ['method'=&gt;__METHOD__]);
}

}

Sekarang mari kita lihat hasilnya dengan mengeksekusi URL http://localhost/hello-yii/web/index.php?r=hello-database/demo-active-query-edit:

Selection_004 Selection_002

Menghapus Data dengan Active Record

Untuk proses hapus dengan active record, kodenya cukup ringkas. Anda hanya perlu mengambil baris mana yang akan dihapus dengan menggunakan findOne(). Kemudian dieksekusi dengan memanggil method delete().
<?php

namespace app\controllers;

use Yii; use yii\filters\AccessControl; use yii\web\Controller; use app\models\Teams;

class HelloDatabaseController extends Controller { ...............

public function actionDemoActiveQueryDelete()
{
    $teams = Teams::findOne(11);
    $teams-&gt;delete();

    return $this-&gt;render('message', ['method'=&gt;__METHOD__]);
}

}

Sekarang mari kita lihat hasilnya dengan mengeksekusi URL http://localhost/hello-yii/web/index.php?r=hello-database/demo-active-query-delete.

Penutup

Dengan menggunakan query builder dan active record, Anda dapat mulai menyimpan data di database yang dalam hal ini adalah MySQL. Kedua API tersebut dapat menangani operasi database seperti select, insert, update, delete, dan beberapa agregasi. Tidak hanya itu, Anda pun dapat melakukan query JOIN dengan menghubungkan dua buah class ActiveRecord berbeda, namun sayangnya belum dapat dibahas di tutorial ini. Bila Anda mempunyai sebuah query yang kompleks, Anda dapat menulisnya dengan menggunakan data access objects yang telah disiapkan oleh Yii2.

Untuk lebih jelasnya Anda dapat membaca Yii2 Official Guide di segmen "Working With Databases" yang membahas data access objects, query builder, dan active record.

(arslan/yiiframework)

0

0

0

share