Pada artikel sebelumnya, penulis telah menjelaskan bagaimana cara melakukan setup project laravel, mulai dari konfigurasi vagrant hingga mengenerate project laravel. Pada artikel kali ini, penulis akan membahas mengenai database migration, seed dan model pada laravel.

Konfigurasi Vim Pada Vagrant

Sebelum memulai ngoding, alangkah baiknya kita melakukan konfigurasi terlebih dahulu terhadap text editor yang akan kita gunakan. Vim merupakan salah satu text editor yang sangat banyak digunakan, terdapat banyak plugin yang dapat kita gunakan untuk memudahkan dalam proses development.

Tahap pertama, kita akan melakukan konfigurasi plugin pathogen pada vim, silahkan jalankan perintah berikut.

mkdir -p ~/.vim/autoload ~/.vim/bundle && \
curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim

Setelah selesai, langkah selanjutnya silahkan lakukan clone plugin berikut per baris.

git clone git://github.com/tpope/vim-sensible.git ~/.vim/bundle/vim-sensible
git clone git://github.com/altercation/vim-colors-solarized.git ~/.vim/bundle/vim-colors-solarized
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
git clone https://github.com/rstacruz/sparkup.git ~/.vim/bundle/sparkup
git clone https://github.com/ctrlpvim/ctrlp.vim.git ~/.vim/bundle/ctrlp.vim

Silahkan atur thema terminal anda menjadi solarized dark. Sekarang silahkan buka file .vimrc dengan vim, jalankan perintah berikut.

vim ~/.vimrc

Kemudian masukkan script untuk konfigurasi seperti berikut.

execute pathogen#infect()
syntax on

set nocompatible
filetype plugin indent on

syntax enable
let g:solarized_termcolors=256
autocmd BufNewFile,BufReadPost *.md set filetype=markdown

set ruler
set number

set expandtab
set shiftwidth=4
set softtabstop=4
set autoindent

set colorcolumn=+1

set autoread

set splitright
set splitbelow

let g:SuperTabClosePreviewOnPopupClose = 1

set rtp+=~/.vim/bundle/vundle
set runtimepath^=~/.vim/bundle/ctrlp.vim
call vundle#rc()
Bundle 'gmarik/vundle'
Bundle 'altercation/vim-colors-solarized'
Bundle 'ctrlpvim/ctrlp.vim'
Bundle 'rstacruz/sparkup'

Jika berhasil, maka output yang diharapkan adalah seperti berikut, vim akan memunculkan warna solarized dark dan juga menampilkan penomoran.

Screenshot from 2016-05-14 22-15-15.png

Belajar Perintah Vim

Sebelum kita lanjut, kita harus benar - benar bisa terlebih dahulu menggunakan vim :D. Tidak seperti text editor biasa yang langsung kita gunakan, vim mempunya beberapa perintah diantaranya adalah.

  • vim nama file biasanya digunakan untuk membuat atau mengubah isi dari file tersebut.
  • i atau insert berfungsi agar kita dalam melakukan perubahan pada file yang sedang aktif dan akan muncul tulisan insert dibagian bawah.
  • esc untuk keluar dari mode edit document atau keluar dari perintah i sehingga document tidak dapat diubah.
  • :w atau write berfungsi untuk menyimpan sebuah document yang telah kita buat atau yang telah kita ubah, jika anda telah selesai melakukan perubahan silahkan tekan esc lalu ketikan perintah :w maka document akan tersimpan.
  • :q atau quit artinya anda keluar dari text editor.
  • :wq atau write and quit artinya anda akan keluar dari text editor dan menyimpan perubahan file.
  • :q! quit artinya anda keluar dari text editor tanpa menyimpan perubahan pada document.
  • :sp nama file split horisontal artinya anda dapat membagi screen window editor anda berdasarkan horisontal.
  • :vsp nama file split vertikal artinya anda dapat membagi screen window editor anda berdasarkan vertikal.
  • ctrl + w + w berfungsi untuk berpindah dari 1 window ke window yang lain.

Membuat Database Migration Pada Laravel

Setelah selesai belajar vim, langkah selanjutnya kita akan mencoba membuat database migration pada laravel. Database migration merupakan salah satu fitur dari laravel untuk mempermudah developer dalam mengembangkan schema database yang ingin digunakan. Di dalam bahasa pemrograman lain juga tersedia database migration seperti ruby on rails pada ruby, flyway pada java dan lain - lain.

Karena project yang akan kita buat adalah sebuah perpustakaan maka disini kita akan membuat database migration mengenai perpustakaan. Berikut adalah ERD dari pada aplikasi perpustakaan yang akan kita buat.

Screenshot from 2016-05-18 21-49-10.png

Bagi yang masih bingung cara membaca ERD tersebut silahkan baca artikel belajar membuat foreign key pada h2 database. Nah setelah mengetahui tentang ERD nya, selanjutnya kita akan membuat database migration dengan menggunakan perintah artisan pada laravel. Untuk membuat database migration untuk tabel buku maka jalankan perintah berikut.

php artisan make:migration create_buku_table --create=tb_buku

Jika berhasil maka outputnya akan seperti berikut.

Screenshot from 2016-05-18 18-12-54.png

Langkah selanjutnya untuk membuat database migration untuk tabel mahasiswa, silahkan jalankan perintah berikut.

php artisan make:migration create_mahasiswa_table --create=tb_mahasiswa

Untuk tabel peminjaman, silahkan jalankan perintah berikut.

php artisan make:migration create_peminjaman_table --create=tb_peminjaman

Setelah selesai, tahap selanjutnya kita akan mengubah schema dari tabel - tabel yang telah kita buat. Silahkan buka file database migration untuk tabel buku yang berada di dalam folder database/migrations, biasanya filenya mengikuti format tanggal dan waktu pada saat membuat database migration, contohnya seperti berikut.

2016_05_18_111241_create_buku_table.php

dimana 2016 adalah tahun, 05 adalah bulan, 18 adalah tanggal dan 111241 adalah sebagai waktu. Silahkan buka file database migration untuk tabel buku dengan perintah.

vim database/migrations/xxxx_xx_xx_xxxxxx_create_buku_table.php

Silahkan ganti dan sesuaikan huruf x dengan tanggal dan waktu pada saat file dibuat. Setelah dibuka, lalu silahkan ubah codingannya seperti berikut.

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateBukuTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tb_buku', function (Blueprint $table) {
            $table->uuid('id_buku');
            $table->string('judul_buku', 50);
            $table->string('nama_pengarang', 50);
            $table->integer('tahun_terbit');
            $table->string('penerbit', 50);
            $table->integer('jumlah_buku');
            $table->string('nomor_rak_buku', 50);
            $table->timestamps();

            $table->primary('id_buku');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tb_buku');
    }
}

Dari codingan diatas dapat dilihat bahwa kita akan membuat sebuah tabel buku dengan nama tabel tb_buku. Disini penulis menggunakan uuid sebagai primary key sehingga tidak akan terjadi kerangkapan data. Langkah selanjutnya silahkan buka database migration untuk tabel mahasiswa dengan perintah.

vim database/migrations/xxxx_xx_xx_xxxxxx_create_mahasiswa_table.php

Kemudian ubah codingannya seperti berikut.

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateMahasiswaTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tb_mahasiswa', function (Blueprint $table) {
            $table->string('npm', 8);
            $table->string('nama', 50);
            $table->string('kelas', 6);
            $table->enum('jenis_kelamin', ['pria', 'wanita']);
            $table->text('alamat');
            $table->timestamps();

            $table->primary('npm');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tb_mahasiswa');
    }
}

Struktur codingan diatas tidak ada yang berbeda dengan codingan sebelumnya, hanya saja disini terlihat berbeda pada bagian jenis kelamin, dimana pada bagian jenis kelamin kita akan menggunakan enum, mengapa enum ? dikarenakan jenis kelamin merupakan sebuah pilihan dan penulis ingin menjaga agar datanya tetap konsisten, jadi jika kita telah menetapkan pria dan wanita adalah sebagai jenis kelamin, maka user tidak dapat melakukan inputan selain pria dan wanita meskipun user ingin melakukan inputan data laki - laki dan perempuan, ini disebabkan data laki - laki dan perempuan tidak terdapat di dalam list enum. Selanjutnya silahkan buka database migration untuk tabel peminjaman, silahkan jalankan perintah berikut.

vim database/migrations/xxxx_xx_xx_xxxxxx_create_peminjaman_table.php

Kemudian ubah codingannya seperti berikut.

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePeminjamanTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tb_peminjaman', function (Blueprint $table) {
            $table->uuid('id_peminjaman');
            $table->date('tanggal_peminjaman');
            $table->date('tanggal_batas_pengembalian');
            $table->timestamps();

            $table->primary('id_peminjaman');

            //relasi foreign key
            $table->string('npm', 8);
            $table->char('id_buku', 36);

            $table->foreign('npm')
                ->references('npm')
                ->on('tb_mahasiswa')
                ->onDelete('cascade')
                ->onUpdate('cascade');

            $table->foreign('id_buku')
                ->references('id_buku')
                ->on('tb_buku');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tb_peminjaman');
    }
}

Codingan untuk tabel peminjaman lumayan berbeda dengan tabel - tabel sebelumnya, mengapa demikian ? dikarenakan disini kita menggunakan foreign key untuk menghubungkan antara tabel buku, barang dan peminjaman. Relasi antara tabel mahasiswa dan peminjaman adalah one to many cascade sehingga apabila data mahasiswa dihapus maka secara otomatis data pada tabel peminjaman juga akan dihapus secara otomatis karena sifat cascade. Berbeda dengan tabel buku, tabel buku memiliki relasi one to many terhadap tabel peminjaman, akan tetapi tidak cascade sehingga apabila tabel buku dihapus, maka tabel peminjaman tidak ikut dihapus.

Setelah semuanya selesai, kita akan menjalankan migration tersebut. Akan tetapi sebelum menjalankan migration, kita harus terlebih dahulu melakukan konfigurasi pada environment. Silahkan buka file .env dengan perintah berikut.

vim .env

Kemudian ubah konfigurasi untuk koneksi database mysql menjadi seperti berikut.

Note : yang diubah hanyalah konfigurasi koneksi database mysql saja, jangan melakukan perubahan pada konfigurasi lain, terutama pada konfigurasi APP_KEY, karena jika key yang digunakan tidak sesuai dengan key yang digenerate pada saat proses pembuatan project maka akan muncul error key tidak valid.

APP_ENV=local
APP_DEBUG=true
APP_KEY=base64:ATM10q5JXcL37xckWACJ7xEIImqAeIRaJR0nRR6RT2A=
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=perpustakaan
DB_USERNAME=root
DB_PASSWORD=root

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

Setelah selesai, lakukan akses database mysql dengan perintah berikut.

mysql -u root -p

Kemudian masukkan password root. Sebenarnya kita menggunakan database mariadb, bukan database mysql akan tetapi perintah yang digunakan adalah sama. Kemudian silahkan buat database perpustakaan dengan perintah berikut.

create database perpustakaan;

Setelah selesai, silahkan keluar dari mysql dengan perintah exit. Kemudian silahkan jalankan database migration dengan perintah berikut.

php artisan migrate

Jika berhasil maka akan muncul output seperti berikut.

root@vagrant-ubuntu-trusty-64:/home/vagrant/Projects/Aplikasi-Perpustakaan# php artisan migrate
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2016_05_18_111241_create_buku_table
Migrated: 2016_05_18_111523_create_mahasiswa_table
Migrated: 2016_05_18_111553_create_peminjaman_table

Membuat Model Pada Laravel

Pada artikel sebelumnya, penulis telah menjelaskan bahwa laravel menggunakan pendekatan mvc pada projectnya. Nah yang pertama kali kita buat adalah model, dimana model ini merupakan represntasi dari pada tabel atau data yang terdapat pada database. Karena pada database migration terdapat 3 tabel maka kita harus membuat 3 model untuk mewakili tabel - tabel yang ada di database migration.

Untuk membuat model untuk buku, silahkan jalankan perintah berikut.

php artisan make:model Buku

Di bagian model, kita harus mengubah codingan sedikit dikarenakan nama tabel yang akan kita gunakan berbeda, silahkan buka model buku pada folder app dengan perintah.

vim app/Buku.php

Kemudian ubah codingannya menjadi seperti berikut.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Buku extends Model
{
    protected $table = 'tb_buku';

    public function peminjamans()
    {
        return $this->hasMany('App\Peminjaman');
    }
}

Wah beda banget sama codingan php biasanya :O, ada namespace dan use. Yups, sebenarnya tidak banyak perbedaan, mungkin jika anda awalnya pernah belajar java, di java terdapat package dan dapat melakukan import maka di php juga bisa akan tetapi hanya berbeda pada penamaan nya saja. Jika di java terdapat package maka di php kita menggunakan namespace, jika di java kita mengenal import maka di php kita mengenal use :). Pada model buku ini, kita mendeklarasikan nama tabel dimana $table ini sebenarnya merupakan override dari class model sehingga kita mengubah nama default dari tabel yang akan kita gunakan. Function peminjamans merupakan function yang penulis buat sendiri dengan tujuan karena model buku mempunya relasi dengan model peminjaman dan relasi ini adalah one to many sehingga pada tabel master yaitu buku dapat memiliki banyak peminjaman.

Untuk membuat model mahasiswa, silahkan jalankan perintah berikut.

php artisan make:model Mahasiswa

Kemudian ubah codingan pada model mahasiswa seperti berikut.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Mahasiswa extends Model
{
    protected $table = 'tb_mahasiswa';

    public function peminjamans()
    {
        return $this->hasMany('App\Peminjaman');
    }
}

Untuk membuat model peminjaman, silahkan jalankan perintah berikut.

php artisan make:model Peminjaman

Kemudian ubah codingan pada model peminjaman seperti berikut.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Peminjaman extends Model
{
    protected $table = 'tb_peminjaman';

    public function buku()
    {
        return $this->belongsTo('App\Buku');
    }

    public function mahasiswa()
    {
        return $this->belongsTo('App\Mahasiswa');
    }
}

Nah berbeda dengan codingan sebelumnya, karena model peminjaman ini hanya memiliki 1 buku dan 1 mahasiswa maka dia harus menggunakan perintah belongsTo untuk melakukan relasi dengan model buku dan mahasiswa.

Membuat Database Seed Pada Laravel

Setelah selesai dengan model, langkah selanjutnya adalah membuat database seed pada laravel. Database seed ini berfungsi sebagai data awal atau bisa disebut sebagai data dami. Biasanya database seed ini digunakan untuk melakukan testing pada aplikasi atau untuk melakukan sebuah uji coba dengan jumlah data yang diperlukan. Karena terdapat 3 model maka kita membuat database seed sebanyak 3, dimana untuk membuat database seed untuk model buku, silahkan jalankan perintah berikut.

php artisan make:seeder BukuTableSeeder

Untuk database seed model mahasiswa, silahkan jalankan perintah berikut.

php artisan make:seeder MahasiswaTableSeeder

Untuk database seed model peminjaman, silahkan jalankan perintah berikut.

php artisan make:seeder PeminjamanTableSeeder

Langkah selanjutnya, silahkan buka file ModelFactory.php yang ada di dalam folder database/factories kemudian silahkan tambahkan codingan seperti berikut.

<?php

/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| Here you may define all of your model factories. Model factories give
| you a convenient way to create models for testing and seeding your
| database. Just tell the factory how a default model should look.
|
*/

$factory->define(App\User::class, function (Faker\Generator $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->safeEmail,
        'password' => bcrypt(str_random(10)),
        'remember_token' => str_random(10),
    ];
});

//seeder buku
$factory->define(App\Buku::class, function (Faker\Generator $faker) {
    return [
        'id_buku' => $faker->uuid,
        'judul_buku' => $faker->sentence($nbWords = 3, $variableNbWords = true),
        'nama_pengarang' => $faker->name,
        'tahun_terbit' => $faker->year,
        'penerbit' => $faker->sentence($nbWords = 3, $variableNbWords = true),
        'jumlah_buku' => $faker->randomDigit,
        'nomor_rak_buku' => $faker->numerify('buku-###')
    ];
});

//seeder mahasiswa
$factory->define(App\Mahasiswa::class, function (Faker\Generator $faker) {
    return [
        'npm' => $faker->numberBetween($min = 00000000, 99999999),
        'nama' => $faker->name,
        'kelas' => $faker->numerify('k-##'),
        'jenis_kelamin' => $faker->randomElement($array = array('pria', 'wanita')),
        'alamat' => $faker->address
    ];
});

//seeder peminjaman
$factory->define(App\Peminjaman::class, function (Faker\Generator $faker) {
    return [
        'id_peminjaman' => $faker->uuid,
        'tanggal_peminjaman' => $faker->date(),
        'tanggal_batas_pengembalian' => $faker->date(),
        'npm' => factory(App\Mahasiswa::class)->create()->npm,
        'id_buku' => factory(App\Buku::class)->create()->id_buku
    ];
});

Untuk melakukan inisialisasi data, kita dapat melakukan nya di bagian model factory, dimana data akan secara otomatis diinisialisasikan oleh library faker. Library faker dapat melakukan generate data yang kita inginkan misalnya seperti nama orang, alamat, penomoran, uuid dan lain sebagainya. Dapat dilihat, bahwa di dalam class model factory, penulis membuat 3 seed untuk masing - masing model, nantinya datanya akan secara otomatis diinsert ke database. Pada bagian peminjaman terdapat perbedaan yaitu pada bagian npm dan id_buku, perbedaan ini dikarenakan pada saat melakukan insert pada peminjaman, maka data buku dan data mahasiswa diwajibkan terlebih dahulu ada. Apabila database seed peminjaman dijalankan maka secara otomatis akan dibuatkan data mahasiswa dan buku terlebih dahulu baru akan dibuatkan data peminjaman.

Kemudian silahkan buka file BukuTableSeeder.php yang terdapat di dalam folder database/seeds kemudian isikan codingan seperti berikut.

<?php

use Illuminate\Database\Seeder;

class BukuTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\Buku::class, 20)->create();
    }
}

Bisa dilihat bahwa pada class ini, jika database seed dijalankan maka akan ada sebanyak 20 data buku yang akan diinput ke database. Hal ini juga berlaku pada database seed mahasiswa dan peminjaman, untuk database seed mahasiswa, silahkan buka file MahasiswaTableSeeder.php kemudian ubah codingannya menjadi seperti berikut.

<?php

use Illuminate\Database\Seeder;

class MahasiswaTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\Mahasiswa::class, 20)->create();
    }
}

Setelah selesai, silahkan buka file PeminjamanTableSeeder.php kemudian ubah codingannya menjadi seperti berikut.

<?php

use Illuminate\Database\Seeder;

class PeminjamanTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\Peminjaman::class, 20)->create();
    }
}

Setelah selesai, langkah selanjutnya adalah kita harus mendeklarasikan masing - masing database seed yang telah kita buat ke dalam konfigurasi database seed. Silahkan buka file DatabaseSeeder.php yang terdapat di dalam folder database/seeds kemudian ubah codingannya menjadi seperti berikut.

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->call(BukuTableSeeder::class);
        $this->call(MahasiswaTableSeeder::class);
        $this->call(PeminjamanTableSeeder::class);
    }
}

Akhirnya kita berada pada tahap yang terakhir :D. Tahap terakhir adalah kita akan menjalankan database seed yang telah kita buat sebelumnya :). Untuk menjalankan database seed silahkan jalankan perintah berikut.

php artisan db:seed

Jika berhasil maka akan muncul output seperti berikut.

root@vagrant-ubuntu-trusty-64:/home/vagrant/Projects/Aplikasi-Perpustakaan# php artisan db:seed
Seeded: BukuTableSeeder
Seeded: MahasiswaTableSeeder
Seeded: PeminjamanTableSeeder

Atau jika anda ingin melakukan database migration sekaligus dengan database seed juga bisa dengan menjalankan perintah berikut.

php artisan migrate:refresh --seed

Berikut adalah output jika anda berhasil menjalankan perintah diatas.

root@vagrant-ubuntu-trusty-64:/home/vagrant/Projects/Aplikasi-Perpustakaan# php artisan migrate:refresh --seed
Rolled back: 2016_05_18_111553_create_peminjaman_table
Rolled back: 2016_05_18_111523_create_mahasiswa_table
Rolled back: 2016_05_18_111241_create_buku_table
Rolled back: 2014_10_12_100000_create_password_resets_table
Rolled back: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2016_05_18_111241_create_buku_table
Migrated: 2016_05_18_111523_create_mahasiswa_table
Migrated: 2016_05_18_111553_create_peminjaman_table
Seeded: BukuTableSeeder
Seeded: MahasiswaTableSeeder
Seeded: PeminjamanTableSeeder

Jika anda masih penasaran dengan database seed apakah telah diinput datanya atau belum, silahkan lakukan pengecekan pada database mariadb anda :).

Sekian tutorial belajar laravel bagian 2, untuk bagian selanjutnya InsyaAllah akan segera di publish dan Terima kasih :).

Apa Itu Laravel ?

Laravel adalah framework berbasis PHP yang open source, menggunakan konsep model–view–controller (MVC). Laravel berada dibawah lisensi MIT.

Beberapa tahun yang lalu, framework laravel tidak begitu terkenal di dalam dunia pemrograman php, akan tetapi dengan perkembangan teknologi tidak dapat dipungkiri sehingga framework laravel berkembang begitu pesat. Terdapat banyak kelebihan di dalam framework laravel salah satu nya adalah memungkinkan kita menggunakan konsep orm, dimana di dalam laravel biasanya kita menggunakan eloquent orm untuk mengabstraksikan antara model object dengan database.

Singkat cerita, penulis ingin belajar mengenai framework laravel, biasanya penulis menggunakan framework codeigniter untuk membuat aplikasi. Framework laravel merupakan framework yang telah banyak digunakan untuk aplikasi production, dan sangat dihandalkan untuk urusan keamanan sebuah website. Jika dilihat dari case study, framework laravel merupakan framework yang bisa dikatakan lumayan lama jika ingin anda pelajari dikarenakan berbagai konfigurasi dan pemahaman yang harus anda kuasai. Pada artikel ini, penulis akan membagi beberapa bagian dikarenakan artikel akan sangat panjang jika membahas laravel hanya pada 1 bagian artikel saja.

Setup Project

Langkah yang pertama kali kita lakukan adalah melakukan setup project. Untuk mempermudah tahap development, kita akan menggunakan beberapa tool berikut diantaranya adalah

  1. Vagrant, bagi yang belum mengerti apa itu vagrant, silahkan lihat di artikel belajar vagrant.
  2. Vim merupakan editor yang akan kita gunakan

sedangkan tool yang lain seperti composer, hhvm, nginx dan lain sebagainya akan kita lakukan konfigurasi pada vagrant.

Membuat Konfigurasi Vagrant

Silahkan buat sebuah folder Belajar-Laravel, kemudian akses folder tersebut dengan menggunakan terminal. Lalu kita akan melakukan inisialisasi vagrant dengan perintah.

vagrant init

maka akan dibentuk sebuah file yaitu Vagrantfile, silahkan buka file tersebut kemudian ubah seperti berikut.

Vagrant.configure(2) do |config|
  config.vm.box = 'ubuntu/trusty64'
  config.vm.provider 'virtualbox' do |v|
    v.memory = 2048
  end
  config.vm.provision 'shell', path: 'setup.sh'
  config.vm.network 'forwarded_port', guest: 80, host: 8080
  config.vm.synced_folder 'Projects', '/home/vagrant/Projects', create: true, owner: 'www-data', group: 'www-data'
end

kemudian silahkan buat sebuah file dengan nama setup.sh untuk konfigurasi provisioning, kemudian isikan codingan shell seperti berikut.

#!/bin/sh
#
# Copyright (C) 2016 Rizki Mufrizal <mufrizalrizki@gmail.com>
#
# Distributed under terms of the MIT license.
#

echo "proses provisioning"

echo "konfigurasi sources dan environment"
cp /vagrant/configuration/sources.list /etc/apt/sources.list
cp /vagrant/configuration/environment /etc/environment

echo "Tambah Repo Git"
sudo add-apt-repository -y ppa:git-core/ppa

echo "Tambah Repo Nginx"
add-apt-repository -y ppa:nginx/stable

echo "Tambah Repo Mariadb"
apt-get install software-properties-common
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
add-apt-repository 'deb [arch=amd64,i386] http://mariadb.biz.net.id/repo/10.1/ubuntu trusty main'

echo "Tambah Repo HHVM"
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x5a16e7281be7a449
add-apt-repository "deb http://dl.hhvm.com/ubuntu $(lsb_release -sc) main"

echo "Tambah Repo Node JS"
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -

apt-get update
apt-get upgrade -y
apt-get dist-upgrade -y

echo "Konfigurasi Mariadb"
apt-get install -y debconf-utils
echo mariadb-server-10.1 mysql-server/root_password password root | debconf-set-selections
echo mariadb-server-10.1 mysql-server/root_password_again password root | debconf-set-selections

apt-get install -y git nginx mariadb-server mariadb-client hhvm vim nodejs

echo "Konfigurasi Virtual Host Nginx"
cp /vagrant/configuration/nginx-vhost /etc/nginx/sites-available/belajarlaravel
ln -s /etc/nginx/sites-available/belajarlaravel /etc/nginx/sites-enabled/
rm /etc/nginx/sites-enabled/default

echo "Konfigurasi HHVM"
/usr/share/hhvm/install_fastcgi.sh
update-rc.d hhvm defaults
/usr/bin/update-alternatives --install /usr/bin/php php /usr/bin/hhvm 60
service nginx restart

echo "Install Composer"
curl -sS https://getcomposer.org/installer | php
mv /home/vagrant/composer.phar /usr/local/bin/composer

Kemudian untuk environment pada vagrant silahkan buat sebuah folder dengan nama configuration dan buat lah file environment, nginx-vhost, sources.list dan .vimrc di dalam nya. Untuk file environment, silahkan isikan dengan value seperti berikut.

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
LC_CTYPE="en_US.UTF-8"
LC_ALL="en_US.UTF-8"

untuk file nginx-vhost seperti berikut.

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  root /home/vagrant/Projects/Aplikasi-Perpustakaan/public;
  index index.html index.php index.htm index.nginx-debian.html;

  server_name perpustakaan.com;
  include hhvm.conf;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }
}

dan yang terakhir untuk file sources.list isikan seperti berikut.

deb http://kambing.ui.ac.id/ubuntu trusty main universe multiverse
deb http://kambing.ui.ac.id/ubuntu trusty-updates main universe multiverse
deb http://security.ubuntu.com/ubuntu trusty-security main universe multiverse

Nah konfigurasi vagrant telah selesai, silahkan jalankan dengan perintah

vagrant up

untuk melakukan akses silahkan jalankan perintah berikut.

vagrant ssh

Membuat Project Laravel Dengan Composer

Untuk membuat project laravel, kita dapat menggunakan composer. Akses folder Projects yang ada di home vagrant melalui terminal. Kemudian jalankan perintah berikut untuk masuk ke mode root.

sudo su

INFO : Semua perintah disini akan menggunakan hak akses root dikarenakan folder Projects diberikan hak akses root.

lalu jalankan perintah berikut untuk membuat project laravel dengan menggunakan composer.

composer create-project --prefer-dist laravel/laravel Aplikasi-Perpustakaan

secara otomatis, composer akan membuatkan anda sebuah project laravel dengan nama Aplikasi-Perpustakaan.

Setelah selesai, yang perlu diperhatikan lagi adalah bahwa agar project laravel benar - benar dapat menggunakan autocomplete pada vim, kita akan menggunakan laravel IDE helper. Silahkan buka kembali terminal pada vagrant anda, silahkan akses folder project laravel anda, lalu ketikan perintah berikut.

composer require barryvdh/laravel-ide-helper

Jika telah selesai, silahkan buka file app.php yang berada di dalam folder config/ dengan perintah berikut.

vim config/app.php

Kemudian cari array providers silahkan tambahkan codingan seperti berikut.

Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class

maka hasilnya akan seperti berikut.

<?php
  'providers' => [

      /*
       * Laravel Framework Service Providers...
       */

      Illuminate\Auth\AuthServiceProvider::class,
      Illuminate\Broadcasting\BroadcastServiceProvider::class,
      Illuminate\Bus\BusServiceProvider::class,
      Illuminate\Cache\CacheServiceProvider::class,
      Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
      Illuminate\Cookie\CookieServiceProvider::class,
      Illuminate\Database\DatabaseServiceProvider::class,
      Illuminate\Encryption\EncryptionServiceProvider::class,
      Illuminate\Filesystem\FilesystemServiceProvider::class,
      Illuminate\Foundation\Providers\FoundationServiceProvider::class,
      Illuminate\Hashing\HashServiceProvider::class,
      Illuminate\Mail\MailServiceProvider::class,
      Illuminate\Pagination\PaginationServiceProvider::class,
      Illuminate\Pipeline\PipelineServiceProvider::class,
      Illuminate\Queue\QueueServiceProvider::class,
      Illuminate\Redis\RedisServiceProvider::class,
      Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
      Illuminate\Session\SessionServiceProvider::class,
      Illuminate\Translation\TranslationServiceProvider::class,
      Illuminate\Validation\ValidationServiceProvider::class,
      Illuminate\View\ViewServiceProvider::class,

      /*
       * Application Service Providers...
       */
      App\Providers\AppServiceProvider::class,
      App\Providers\AuthServiceProvider::class,
      App\Providers\EventServiceProvider::class,
      App\Providers\RouteServiceProvider::class,

      Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class

],

Setelah selesai, silahkan jalankan perintah berikut untuk melakukan generate ide helper dengan perintah

php artisan ide-helper:generate

Jika berhasil maka akan muncul output seperti berikut.

Screenshot from 2016-05-14 10-44-28.png

Melakukan Setting Domain

Setelah melakukan konfigurasi seperti diatas, langkah selanjutnya adalah membuat domain sendiri, sehingga kita akan melakukan akses aplikasi dengan menggunakan nama domain. Silahkan buka file hosts dengan perintah

sudo nano /etc/hosts

lalu tambahkan script berikut.

127.0.0.1       perpustakaan.com

Silahkan akses web anda pada browser di http://perpustakaan.com:8080, jika berhasil maka outputnya seperti berikut.

Screenshot from 2016-05-14 17-48-57.png

Sekian tutorial belajar laravel bagian 1, untuk bagian selanjutnya InsyaAllah akan segera di publish dan Terima kasih :).

Apa Itu Angular JS ?

Angular JS adalah salah satu framework javascript yang mengusungkan pola MV* dan dikembangkan oleh google.

Angular JS biasanya digunakan sebagai framework di bagian front end suatu website. Salah satu kelebihan dari angular js ini adalah data binding sehingga antara model dan controller datanya akan dilakukan sinkronisasi secara asynchronous. Kelebihan angular yang lain adalah angular dapat melakukan routing, membuat sebuah directive dan biasanya digunakan sebagai client untuk sebuah web service.

Membuat Hello Word Dengan Angular JS

Untuk mempermudah pemahaman, kita akan langsung mencoba membuat hello word dengan menggunakan angular js :D. Untuk mendownload kebutuhan dependency angular, penulis akan menggunakan bower, karena menggunakan bower maka anda diwajibkan untuk melakukan instalasi node js. Bagi anda yang belum melakukan instalasi node js, silahkan lihat di Instalasi Perlengkapan Coding Node JS. Silahkan buat sebuah folder dengan nama Belajar-AngularJS, kemudian akses foder tersebut dengan terminal. Kemudian jalankan perintah berikut.

bower init

Kemudian silahkan isi konfigurasinya seperti berikut.

Screenshot from 2016-05-03 10-40-10.png

Lalu tahap selanjutnya, kita akan mendownload dependency library yang diperlukan, silahkan jalankan perintah berikut.

bower install bootstrap angular --save

perintah diatas akan mendownload dependency bootstrap untuk tampilan web nya dan angular js. Setelah selesai, silahkan buat sebuah file index.html lalu isikan codingan seperti berikut.

<!DOCTYPE html>
<html lang="en" ng-app>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Belajar Angular JS</title>

        <!-- Bootstrap -->
        <link href="./bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>

        <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.2/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <![endif]-->
    </head>
    <body>

        <div class="container">
            <div class="row">
                <div class="col-lg-4">
                    <div class="form-group">
                        <label>Nama</label>
                        <input type="text" class="form-control" placeholder="Masukkan Nama Anda" ng-model="nama"/>
                    </div>
                </div>
            </div>

            <h2>Hello {{nama}}</h2>
        </div>

        <script type="text/javascript" src="./bower_components/jquery/dist/jquery.min.js"></script>
        <script type="text/javascript" src="./bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
        <script type="text/javascript" src="./bower_components/angular/angular.min.js"></script>
    </body>
</html>

Berikut adalah penjelasan mengenai codingan diatas.

  • ng-app berfungsi untuk mendeklarasikan bahwa file html ini akan dihandle oleh angular js.
  • ng-model berfungsi sebagai model yang dapat menampung data, nantinya data ini akan ditampilkan.
  • {{nama}} berfungsi untuk menampilkan data, di dalam angular, kita akan menggunakan tanda {{}} untuk menampilkan data

Nah setelah selesai, selanjutnya kita akan menjalankan file index.html, untuk menjalankannya, kita akan menggunakan plugin http-server dari node js :D. Bagi anda yang masing bingung dengan node js, silahkan simak di artikel instalasi perlengkapan node js. Untuk melakukan instalasi http-server, silahkan jalankan perintah berikut.

 npm install -g http-server

Setelah selesai, jalankan perintah berikut pada root project untuk menjalankan http-server.

http-server

Jika berhasil, maka di terminal akan muncul output seperti berikut.

Starting up http-server, serving ./
Available on:
  http://127.0.0.1:8080
Hit CTRL-C to stop the server

Kemudian silahkan akses http://127.0.0.1:8080 pada browser anda.

Screenshot from 2016-05-03 10-40-11.png

Membuat CRUD Sederhana Dengan Angular JS

Setelah selesai membuat hello word dengan angular js, tahap selanjutnya kita akan membuat fungsi crud dengan menggunakan angular. Silahkan ubah file index.html seperti berikut.

<!DOCTYPE html>
<html lang="en" ng-app="Belajar-AngularJS">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Belajar Angular JS</title>

        <!-- Bootstrap -->
        <link href="./bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>

        <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.2/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <![endif]-->
    </head>
    <body ng-controller="AppController">

        <div class="container">
            <div class="row">
                <div class="col-lg-2">
                    <div class="form-group">
                        <label>Nama</label>
                        <input type="text" class="form-control" placeholder="Masukkan Nama Anda" ng-model="nama"/>
                    </div>

                    <h2>Hello {{nama}}</h2>
                </div>
                <div class="col-lg-10">

                    <p></p>

                    <button ng-click="tambahBarang()" type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal">
                        Tambah Barang
                    </button>

                    <p></p>

                    <table class="table table-striped table-bordered table-hover">
                        <thead>
                            <tr>
                                <th class="text-center">ID Barang</th>
                                <th class="text-center">Nama Barang</th>
                                <th class="text-center">Jenis Barang</th>
                                <th class="text-center">Tanggal Kadaluarsa</th>
                                <th class="text-center">Aksi</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr ng-repeat="b in dataBarang">
                                <td>{{b.idBarang}}</td>
                                <td>{{b.namaBarang}}</td>
                                <td>{{b.jenisBarang}}</td>
                                <td>{{b.tanggalKadaluarsa}}</td>
                                <td class="text-center">
                                    <button type="button" class="btn btn-success" data-toggle="modal" data-target="#modal" ng-click="editBarang(b)">
                                        <i class="glyphicon glyphicon-pencil"></i>
                                    </button>
                                    <button type="button" class="btn btn-danger" ng-click="hapusBarang(b)">
                                        <i class="glyphicon glyphicon-trash"></i>
                                    </button>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>

        <!-- Modal -->
        <div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                        <h4 ng-hide="enable" class="modal-title">Tambah Barang</h4>
                        <h4 ng-show="enable" class="modal-title">Edit Barang</h4>
                    </div>
                    <div class="modal-body">
                        <form>
                            <div ng-show="enable" class="form-group">
                                <label>ID Barang</label>
                                <input type="text" class="form-control" ng-model="inputDataBarang.idBarang" disabled/>
                            </div>
                            <div class="form-group">
                                <label>Nama Barang</label>
                                <input type="text" class="form-control" placeholder="Masukkan Nama Barang" ng-model="inputDataBarang.namaBarang"/>
                            </div>
                            <div class="form-group">
                                <label>Jenis Barang</label>
                                <select class="form-control" ng-model="inputDataBarang.jenisBarang">
                                    <option value="" disabled>Pilih Jenis Barang</option>
                                    <option value="gas">Gas</option>
                                    <option value="padat">Padat</option>
                                    <option value="cair">Cair</option>
                                </select>
                            </div>
                            <div class="form-group">
                                <label>Tanggal Kadaluarsa</label>
                                <input type="date" class="form-control" placeholder="Masukkan Tanggal Kadaluarsa" ng-model="inputDataBarang.tanggalKadaluarsa"/>
                            </div>
                        </form>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-warning" data-dismiss="modal">Batal</button>
                        <button ng-hide="enable" type="button" class="btn btn-success" data-dismiss="modal" ng-click="simpanBarang(inputDataBarang)">Simpan</button>
                        <button ng-show="enable" type="button" class="btn btn-success" data-dismiss="modal" ng-click="updateBarang(inputDataBarang)">Update</button>
                    </div>
                </div>
            </div>
        </div>

        <script type="text/javascript" src="./bower_components/jquery/dist/jquery.min.js"></script>
        <script type="text/javascript" src="./bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
        <script type="text/javascript" src="./bower_components/angular/angular.min.js"></script>
        <script type="text/javascript" src="./app.js"></script>
    </body>
</html>

Codingan diatas berfungsi untuk melakukan proses crud dimana untuk proses memasukkan data, kita hanya menggunakan fungsi modal dari bootstrap.

Kemudian silahkan buat sebuah file app.js kemudian isikan codingan seperti berikut.

'use strict';

angular.module('Belajar-AngularJS', [])
  .controller('AppController', ['$scope', function($scope) {

    $scope.dataBarang = [];
    $scope.inputDataBarang = {};

    function generateUUID() {
      var d = new Date().getTime();
      if (window.performance && typeof window.performance.now === "function") {
        d += performance.now();
      }
      var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
      });
      return uuid;
    }

    $scope.tambahBarang = function() {
      $scope.enable = false;
      $scope.inputDataBarang.idBarang = '';
      $scope.inputDataBarang.namaBarang = '';
      $scope.inputDataBarang.jenisBarang = '';
      $scope.inputDataBarang.tanggalKadaluarsa = '';
    };

    $scope.simpanBarang = function(barang) {
      $scope.dataBarang.push({
        'idBarang': generateUUID(),
        'namaBarang': barang.namaBarang,
        'jenisBarang': barang.jenisBarang,
        'tanggalKadaluarsa': barang.tanggalKadaluarsa
      });
    };

    $scope.editBarang = function(barang) {
      $scope.enable = true;
      $scope.index = $scope.dataBarang.indexOf(barang);
      $scope.inputDataBarang.idBarang = barang.idBarang;
      $scope.inputDataBarang.namaBarang = barang.namaBarang;
      $scope.inputDataBarang.jenisBarang = barang.jenisBarang;
      $scope.inputDataBarang.tanggalKadaluarsa = barang.tanggalKadaluarsa;
    };

    $scope.updateBarang = function(barang) {
      $scope.dataBarang[$scope.index].idBarang = barang.idBarang;
      $scope.dataBarang[$scope.index].namaBarang = barang.namaBarang;
      $scope.dataBarang[$scope.index].jenisBarang = barang.jenisBarang;
      $scope.dataBarang[$scope.index].tanggalKadaluarsa = barang.tanggalKadaluarsa;
    };

    $scope.hapusBarang = function(barang) {
      var result = confirm('Anda ingin menghapus data barang ?');
      if (result) {
        $scope.index = $scope.dataBarang.indexOf(barang);
        $scope.dataBarang.splice($scope.index, 1);
      }
    }

  }]);

Codingan diatas berfungsi untuk proses crud pada bagian angular js. Function generateUUID berfungsi untuk melakukan generate id barang secara random. Jika telah selesai, silahkan jalankan file index.html, jika berhasil maka akan muncul output seperti berikut.

output untuk proses insert.

Screenshot from 2016-05-03 10-41-06.png

output untuk proses select.

Screenshot from 2016-05-03 10-41-07.png

output untuk proses update

Screenshot from 2016-05-03 10-41-16.png

output untuk proses delete

Screenshot from 2016-05-03 10-41-24.png

Sekian tutorial belajar angular js dan Terima kasih :). Untuk source code lengkap, penulis publish di Belajar Angular JS.

Apa Itu Socket ?

Socket adalah mekanisme komunikasi untuk pertukaran data antar aplikasi yang terdapat di dalam sebuah mesin maupun beda mesin dan pertukaran ini terjadi pada sebuah jaringan komputer.

Untuk membangun sebuah aplikasi yang berbasis socket, kita dapat menggunakan 2 jenis socket yang berbeda yaitu :

  • TCP Socket : menggunakan konsep connection oriented dan reliable data transfer sehingga aplikasi yang dibangun dengan TCP Socket tidak mempedulikan lama waktu sebuah pengiriman data akan tetapi sangat mementingkan ketepatan data. Konsep connection oriented adalah suatu proses pengiriman data disertai dengan tanggung jawab sehingga ketika data sampai pada tujuan akan ada pemberitahuan atau jika terjadi kesalahan pada saat pengiriman data maka data tersebut akan dikirim kembali ke tujuannya. Konsep reliable data transfer adalah sebuah proses pengiriman data dengan menggunakan nomor urut sehingga pada saat diterima, data akan tersusun berdasarkan nomor urut tersebut.

  • UDP Socket : menggunakan konsep connectionless oriented dan unreliable data transfer sehingga aplikasi yang dibangun dengan UDP Socket tidak mementingkan ketepatan data tetapi lebih mementingkan akan delay waktu pada saat proses pengiriman data. Konsep connectionless oriented adalah suatu proses pengiriman data tidak disertai dengan tanggung jawab sehingga jika terjadi kesalahan pada saat proses pengiriman maka data tersebut tidak akan dikirim ulang ke tujuan. Konsep unreliable data transfer adalah sebuah proses pengiriman data dalam bentuk datagram tanpa nomor urut.

Implementasi TCP Socket

Pada artikel ini, penulis akan melakukan implementasi TCP Socket dengan menggunakan bahasa pemrograman java. Silahkan buat sebuah file dengan nama ServerChat.java kemudian masukkan codingan seperti berikut.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;

/*
 * ServerChat.java
 * Copyright (C) 2016 Rizki Mufrizal <mufrizalrizki@gmail.com>
 *
 * Distributed under terms of the MIT license.
 */

 public class ServerChat {

    private static final int PORT = 9001;
    private static HashSet<String> names = new HashSet<>();
    private static HashSet<PrintWriter> printWriters = new HashSet<>();

    public static void main(String[] args) throws IOException {
        System.out.println("server jalan pada port : " + PORT);
        ServerSocket serverSocket = new ServerSocket(PORT);
        try {
            while (true) {
                new Handler(serverSocket.accept()).start();
            }
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            serverSocket.close();
        }
    }

    private static class Handler extends Thread {

        private String name;
        private Socket socket;
        private BufferedReader bufferedReader;
        private PrintWriter printWriter;

        public Handler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                printWriter = new PrintWriter(socket.getOutputStream(), true);

                while (true) {
                    printWriter.println("submitname");
                    name = bufferedReader.readLine();

                    if (name == null) {
                        return;
                    }

                    synchronized (names) {
                    
                        if (!names.contains(name)) {
                            names.add(name);
                            break;
                        }
                    
                    }
                }

                printWriter.println("nameaccepted");
                printWriters.add(printWriter);

                while (true) {
                    String input = bufferedReader.readLine();
                    
                    if (input == null) {
                        return;
                    }
                    
                    printWriters.stream().forEach((pw) -> {
                        pw.println("message " + name + " : " + input);
                    });

                }

            } catch (IOException e) {
                System.out.println(e);
            } finally {

                if (name != null) {
                    names.remove(name);
                }
            
                if (printWriter != null) {
                    printWriters.remove(printWriter);
                }
            
                try {
                    socket.close();
                } catch (IOException e) {
                    System.out.println(e);
                }
            }
        }
    }
}

Pada codingan diatas, kita membuat 2 class di dalam satu file, dimana class Handler kita lakukan inheritance terhadap class Thread. Fungsinya adalah kita akan membuka koneksi dan menunggu permintaan koneksi dari client. Pada saat client melakukan koneksi ke server maka client akan melakukan syncronize dengan server atau client akan melakukan request ke server, kemudian server akan melakukan sycronize terhadap seluruh client yang terhubung pada jaringan sehingga ketika ada suatu aksi maka server akan memberikan response kepada semua client meskipun client tersebut tidak memberikan request ke server. Pada codingan diatas, server akan berjalan pada port 9001 sehingga client harus bisa melakukan koneksi pada jaringan dan port yang sama dengan server.

Tahap selanjutnya, kita akan membuat sebuah client, silahkan buat sebuah file dengan nama ClientChat.java kemudian masukkan codingan berikut.

import java.awt.event.ActionEvent;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/*
 * ClientChat.java
 * Copyright (C) 2016 Rizki Mufrizal <mufrizalrizki@gmail.com>
 *
 * Distributed under terms of the MIT license.
 */

public class ClientChat {

    private BufferedReader bufferedReader;
    private PrintWriter printWriter;
    private JFrame jFrame = new JFrame("aplikasi chat");
    private JTextField jTextField = new JTextField(40);
    private JTextArea jTextArea = new JTextArea(8, 40);

    public ClientChat() {
        jTextField.setEditable(Boolean.FALSE);
        jTextArea.setEditable(Boolean.FALSE);
        jFrame.setSize(500, 500);
        jFrame.getContentPane().add(jTextField, "North");
        jFrame.getContentPane().add(new JScrollPane(jTextArea), "Center");
        Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
        jFrame.setLocation((dimension.width / 2) - (jFrame.getSize().width / 2), (dimension.height / 2) - (jFrame.getSize().height / 2));

        jTextField.addActionListener((ActionEvent e) -> {
            printWriter.println(jTextField.getText());
            jTextField.setText("");
        });
    }

    public String getServerAddress() {
        return JOptionPane.showInputDialog(
            jFrame,
            "masukan ip address",
            "selamat datang di aplikasi chat",
            JOptionPane.QUESTION_MESSAGE
        );
    }

    public String getName() {
        return JOptionPane.showInputDialog(
            jFrame,
            "Masukkan nama anda",
            "selamat datang di aplikasi chat",
            JOptionPane.QUESTION_MESSAGE
        );
    }

    private void run() throws IOException {
        String serverAddress = getServerAddress();
        Socket socket = new Socket(serverAddress, 9001);
        bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        printWriter = new PrintWriter(socket.getOutputStream(), true);

        while (true) {
            String line = bufferedReader.readLine();
            if (line.startsWith("submitname")) {
                printWriter.println(getName());
            } else if (line.startsWith("nameaccepted")) {
                jTextField.setEditable(Boolean.TRUE);
            } else if (line.startsWith("message")) {
                jTextArea.append(line.substring(8) + "\n");
            }
        }
    }

    public static void main(String[] args) throws IOException {
        ClientChat clientChat = new ClientChat();
        clientChat.jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        clientChat.jFrame.setVisible(Boolean.TRUE);
        clientChat.run();
    }

}

Pada codingan diatas, kita membuat sebuah aplikasi chat untuk bagian client, port telah kita tentukan sesuai dengan port server yaitu 9001, sedangkan IP akan didefinisikan sendiri oleh user yang akan melakukan inputan. Aplikasi ini digunakan untuk melakukan chat secara group, misalkan jika terdapat 2 user maka kita dapat melakukan chat secara serentak, ketika user 1 melakukan chat maka secara otomatis user 2 akan mendapatkan balasan chat dari user 1 begitu pula sebaliknya.

Uji Coba TCP Socket

Untuk melakukan uji coba TCP Socket, kita dapat menggunakan aplikasi wireshark. Untuk melakukan instalasi wireshark, silahkan tambahkan ppa berikut.

sudo add-apt-repository ppa:wireshark-dev/stable

Kemudian lakukan update

sudo apt-get update

lalu lakukan instalasi aplikasi dengan perintah

sudo apt-get install wireshark

Tahap selanjutnya, silahkan lakukan compile kedua source code yang telah buat tadi, jalankan dengan perintah berikut untuk melakukan compile kedua file ServerChat.java.

javac ServerChat.java

kemudian jalankan dengan perintah

java ServerChat

Untuk melakukan compile file ClientChat.java maka jalankan perintah berikut.

javac ClientChat.java

kemudian jalankan dengan perintah

java ClientChat

Jalankan ClientChat sebanyak 2x sehingga akan muncul 2 form, 2 form ini merupakan representasi dari 2 client sehingga silahkan masukkan IP anda dengan 127.0.0.1 kemudian masukkan nama yang berbeda pada setiap form, kemudian lakukan chat antar client. Berikut adalah output dari aplikasi client tersebut.

Screenshot from 2016-04-14 14:22:40.png

Langkah selanjutnya adalah kita akan melakukan test dengan menggunakan wireshark, silahkan buka wireshark anda, berikut adalah tampilan dasboard nya.

Screenshot from 2016-04-14 16:38:33.png

Pada bagian dasboard terdapat proses capture, silahkan anda pilih any. Setelah selesai maka akan muncul seperti berikut.

Screenshot from 2016-04-14 16:39:42.png

arti dari gambar tersebut adalah aplikasi wireshark dengan melakukan capture terhadap jaringan yang sedang berjalan. Kemudian jalankan kembali aplikasi chat yang telah kita buat, pada saat aplikasi chat bagian client dijalankan maka pada aplikasi wireshark akan muncul seperti berikut.

Screenshot from 2016-04-14 19:39:10.png

Kemudian lakukan chat antar 2 client maka anda juga akan melihat ada proses pertukaran paket pada protokol TCP. Berikut adalah output ketika penulis melakukan chat.

Screenshot from 2016-04-14 19:38:17.png

Implementasi UDP Socket

Setelah melakukan implementasi TCP Socket, tahap selanjutnya kita akan melakukan implementasi UDP Socket dengan bahasa pemrograman java :). Silahkan buat sebuah file dengan nama UDPServer.java lalu masukkan codingan seperti berikut.

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/*
 * UDPServer.java
 * Copyright (C) 2016 Rizki Mufrizal <mufrizalrizki@gmail.com>
 *
 * Distributed under terms of the MIT license.
 */

public class UDPServer {

    public static void main(String args[]) {
        DatagramSocket datagramSocket = null;

        try {
            datagramSocket = new DatagramSocket(8888);

            byte[] buffer = new byte[65536];
            DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length);

            System.out.println("socket server jalan, menunggu data yang dikirim");

            while (true) {
                datagramSocket.receive(datagramPacket);
                byte[] data = datagramPacket.getData();
                String s = new String(data, 0, datagramPacket.getLength());

                System.out.println(datagramPacket.getAddress().getHostAddress() + " : " + datagramPacket.getPort() + " : " + s);

                s = "data yang terkirim : " + s;
                DatagramPacket packet = new DatagramPacket(s.getBytes(), s.getBytes().length, datagramPacket.getAddress(), datagramPacket.getPort());
                datagramSocket.send(packet);
            }

        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

Pada codingan diatas dapat dilihat bahwa server akan menunggu data yang dikirim dari client, data yang dikirim adalah packet dalam bentuk datagram sehingga packet tersebut tidak memiliki penomoran pada saat pengiriman berlangsung.

Untuk kebutuhan testing, kita juga akan membuat sebuah client udp, silahkan buat sebuah file dengan nama UDPClient.java kemudian masukkan codingan berikut.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/*
 * UDPClient.java
 * Copyright (C) 2016 Rizki Mufrizal <mufrizalrizki@gmail.com>
 *
 * Distributed under terms of the MIT license.
 */

public class UDPClient {

    public static void main(String args[]) {
        DatagramSocket datagramSocket = null;
        String s;
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

        try {
            datagramSocket = new DatagramSocket();
            InetAddress inetAddress = InetAddress.getByName("127.0.0.1");

            while (true) {
                System.out.print("Masukkan pesan anda : ");
                s = bufferedReader.readLine();
                byte[] b = s.getBytes();

                DatagramPacket datagramPacket = new DatagramPacket(b, b.length, inetAddress, 8888);
                datagramSocket.send(datagramPacket);

                byte[] buffer = new byte[65536];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                datagramSocket.receive(packet);

                byte[] data = packet.getData();
                s = new String(data, 0, packet.getLength());

                System.out.println(packet.getAddress().getHostName() + " : " + packet.getPort() + " : " + s);
            }

        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

Codingan diatas berfungsi sebagai client, dimana pada saat client dijalankan, anda dapat mengirim pesan ke server lalu server akan mengembalikan pesan anda kembali. Jika terdapat banyak client, maka pesan tersebut tidak akan syncronize dengan client yang lain akan tetapi pesan tersebut hanya syncronize dengan server.

Uji Coba UDP Socket

Uji coba UDP dapat menggunakan nmap, wireshark dan juga aplikasi client yang telah kita buat tadi. Kita akan melakukan uji coba terlebih dahulu dengan menggunakan nmap. Silahkan lakukan instalasi nmap dengan perintah berikut.

sudo apt-get install nmap

Langkah selanjutnya silahkan lakukan compile file UDPServer.java lalu jalankan file tersebut. Kemudian kita akan mengecek terlebih dahulu status jaringan dengan perintah.

netstat -u -ap

Maka akan muncul output seperti berikut.

(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
udp        0      0 *:ipp                   *:*                                 -               
udp        0      0 *:mdns                  *:*                                 12151/          
udp        0      0 *:mdns                  *:*                                 -               
udp        0      0 *:51757                 *:*                                 -               
udp        0      0 localhost:52426         localhost:52426         ESTABLISHED -               
udp        0      0 *:52813                 *:*                                 -               
udp        0      0 10.42.0.1:domain        *:*                                 -               
udp        0      0 rizki-HP-431-Not:domain *:*                                 -               
udp        0      0 *:bootps                *:*                                 -               
udp        0      0 *:bootpc                *:*                                 -               
udp6       0      0 [::]:8888               [::]:*                              21206/java      
udp6       0      0 [::]:mdns               [::]:*                              -               
udp6       0      0 [::]:51861              [::]:*                              -               
udp6       0      0 [::]:4466               [::]:*                              - 

Bisa dilihat bahwa UDP Server telah berjalan sukses, bisa dilihat pada bagian PID/Program name terdapat kalimat java dan bertepatan dengan port 8888 yang telah kita konfigurasi pada codingan java. Langkah selanjutnya, untuk mengirim pesan ke server, silahkan jalankan perintah berikut.

ncat -vv localhost 8888 -u

Maksud dari perintah diatas adalah

  • -vv berfungsi untuk memberikan informasi secara detail
  • -u berfungsi untuk mendeklarasikan protokol UDP

Jika berhasil, maka akan muncul output seperti berikut.

Ncat: Version 6.40 ( http://nmap.org/ncat )
libnsock nsi_new2(): nsi_new (IOD #1)
libnsock nsock_connect_udp(): UDP connection requested to 127.0.0.1:8888 (IOD #1) EID 8
libnsock nsock_trace_handler_callback(): Callback: CONNECT SUCCESS for EID 8 [127.0.0.1:8888]
Ncat: Connected to 127.0.0.1:8888.
libnsock nsi_new2(): nsi_new (IOD #2)
libnsock nsock_read(): Read request from IOD #1 [127.0.0.1:8888] (timeout: -1ms) EID 18
libnsock nsock_readbytes(): Read request for 0 bytes from IOD #2 [peer unspecified] EID 26

Kemudian silahkan ketikan pesan yang anda inginkan, jika berhasil maka anda akan mendapatkan response dari server, berikut adalah output nya.

Ncat: Version 6.40 ( http://nmap.org/ncat )
libnsock nsi_new2(): nsi_new (IOD #1)
libnsock nsock_connect_udp(): UDP connection requested to 127.0.0.1:8888 (IOD #1) EID 8
libnsock nsock_trace_handler_callback(): Callback: CONNECT SUCCESS for EID 8 [127.0.0.1:8888]
Ncat: Connected to 127.0.0.1:8888.
libnsock nsi_new2(): nsi_new (IOD #2)
libnsock nsock_read(): Read request from IOD #1 [127.0.0.1:8888] (timeout: -1ms) EID 18
libnsock nsock_readbytes(): Read request for 0 bytes from IOD #2 [peer unspecified] EID 26
hello rizki mufrizal
libnsock nsock_trace_handler_callback(): Callback: READ SUCCESS for EID 26 [peer unspecified] (21 bytes): hello rizki mufrizal.
libnsock nsock_trace_handler_callback(): Callback: WRITE SUCCESS for EID 35 [127.0.0.1:8888]
libnsock nsock_readbytes(): Read request for 0 bytes from IOD #2 [peer unspecified] EID 42
libnsock nsock_trace_handler_callback(): Callback: READ SUCCESS for EID 18 [127.0.0.1:8888] (42 bytes): data yang terkirim : hello rizki mufrizal.
data yang terkirim : hello rizki mufrizal
libnsock nsock_readbytes(): Read request for 0 bytes from IOD #1 [127.0.0.1:8888] EID 50

Jika kita cek pada bagian server, maka akan muncul output seperti berikut.

socket server jalan, menunggu data yang dikirim
127.0.0.1 : 34481 : hello rizki mufrizal

Tahap yang terakhir kita akan melakukan uji coba dengan menggunakan wireshark, silahkan matikan UDPServer, lalu jalankan kembali wireshark dan jalankan UDPServer. Setelah selesai, silahkan jalankan UDPClient kemudian silahkan kirimkan pesan. Berikut adalah output ketika terjadi pengiriman pesan dengan UDP Socket.

Screenshot from 2016-04-14 19:35:24.png

Sekian tutorial belajar socket programming dan Terima kasih :)

Artikel - artikel yang lalu, penulis membuat tulisan mengenai database PostgreSQL, akan tetapi pada penulisan ini kita akan mencoba menggunakan database h2 :).

Apa Itu Foreign Key ?

Foreign Key adalah sebuah column atau field yang berfungsi sebagai kunci tamu dimana kunci ini akan kita gunakan untuk relasi antar tabel.

Jika anda telah terbiasa dengan database yang memiliki arsitektur RDBMS maka anda tidak asing lagi dengan namanya primary key. Setiap tabel di dalam database wajib memiliki primary key, dikarenakan primary key ini berfungsi sebagai kunci unik untuk membedakan antara 1 row atau record dengan record yang lain.

Apa hubungan antara primary key dan foreign key ? biasanya primary key kita gunakan sebagai kata kunci, sedangkan foreign key biasanya diambil dari primary key sebuah tabel, contoh nya seperti berikut.

NPM Nama Mahasiswa Kelas
58412085 Rizki Mufrizal 4IA04
12345678 Mufrizal 4IA00

dan berikut adalah tabel nilai uts.

ID Nilai UTS UAS NPM
N01 100 100 58412085
N02 90 90 12345678
N03 80 80 58412085

Dari kedua tabel diatas dapat dilihat adanya relasi antara tabel mahasiswa dan tabel nilai. Pada tabel mahasiswa terdapat 1 primary key yaitu npm sedangkan pada tabel nilai kita memiliki 1 primary key juga yaitu id nilai. Sesuai dengan pembahasan kita yaitu foreign key, pada kedua tabel diatas terdapat 1 foreign key. Fireign key tersebut berada pada tabel nilai yaitu npm, dimana npm ini adalah primary key yang terdapat pada tabel mahasiswa.

Bagaimana Cara Menentukan Foreign Key ?

Kebiasaan seorang mahasiswa bingung bagaimana cara menetukan relasi antar tabel, bahkan ada beberapa mahasiswa yang secara langsung membuat aplikasi tanpa membuat normalisasi dan ERD, padahal normalisasi dan ERD adalah sesuatu yang wajib dibuat. Pada artikel ini, kita akan menggunakan cara cepat untuk menentukan relasi antar tabel. Misalkan penulis mempunyai data seperti berikut.

NB JB TK HSB JBT TH TT NP JBD THPB
Rinso Cair 01-01-2016 Rp 1000 10 Rp 5000 02-02-2016 Rizki 5 Rp 5000
Baju Padat 01-02-2016 Rp 2000 50 Rp 10000 02-02-2016 Rizki 5 Rp 10000
Rinso Cair 01-01-2016 Rp 1000 10 Rp 10000 02-02-2016 Mufrizal 10 Rp 10000

Ket :

  • NB : Nama Barang
  • JB : Jenis Barang
  • TK : Tanggal Kadaluarsa
  • TH : Total Harga
  • TT : Tanggal Transaksi
  • NP : Nama Pembeli
  • HSB : Harga Satuan Barang
  • JBT : Jumlah Barang Tersedia
  • JBD : Jumlah Barang Dibeli
  • THPB : Total Harga Per Barang

Data diatas merupakan data mentah atau bisa dibilang data diatas masih terdapat duplicate. Biar gampang, silahkan copy data tersebut ke libre office atau excel. Jika sudah kita akan membedakan data - data tersebut. Dari tabel diatas, bisa dilihat bahwa terdapat terdapat column - column yang doubel seperti nama barang, jenis barang, tanggal kadaluarsa, harga satuan barang dan jumlah barang yang tersedia. Column - column tersebut merupakan data barang, dimana data tersebut kita kelompokkan menjadi satu tabel, maka tabel barang akan menjadi seperti berikut.

ID Barang Nama Barang Jenis Barang Tanggal Kadaluarsa Harga Satuan Barang Jumlah Barang Tersedia
B01 Rinso Cair 01-01-2016 Rp 1000 10
B02 Baju Padat 01-02-2016 Rp 2000 50

Pada tabel diatas kita menambahkan satu column yaitu id barang, id barang ditambahkan karena pada tabel sebelum nya belum terdapat primary key. Setelah selesai, langkah selanjutnya kita akan melakukan spesifikasi untuk tabel penjualan, berikut adalah bentuk tabel nya.

Kode Transaksi Penjualan Tanggal Transaksi Nama Pembeli Total Harga
T01 02-02-2016 Rizki Rp 5000
T02 02-02-2016 Mufrizal Rp 10000

Lagi - lagi penulis menambahkan sebuah column kode transaksi penjualan sebagai primary key. Tabel penjualan ini akan berisi mengenai data - data penjualan dalam sekali transaksi, akan tetapi di dalam sekali transaksi terdapat beberapa barang yang berbeda sehingga kita akan membuat tabel penjualan detail. Tabel penjualan detail ini akan memiliki relasi ke tabel penjualan dan tabel barang, dimana relasi tabel penjualan ke tabel penjualan detail memiliki relasi one to many sama seperti tabel barang dan tabel penjualan detail sehingga seluruh data akan konsisten dan mengurangi kerangkapan data. Berikut adalah tabel penjualan detail.

Kode Transaksi Penjualan Detail Jumlah Barang Total Harga Per Barang Kode Transaksi Penjualan ID Barang
TD01 5 Rp 5000 T01 B01
TD02 5 Rp 10000 T01 B02
TD03 10 Rp 10000 T02 B01

Dari tabel diatas terdapat 3 column yang penulis tambahkan yaitu column kode transaksi penjualan detail sebagai primary key, kode transaksi penjualan sebagai foreign key dan id barang sebagai foreign key juga. Berikut adalah tampilan ERD nya seperti berikut.

Screenshot from 2016-03-26 14:07:44.png

Dari ERD diatas penulis membuat 2 garis yang berbeda yaitu ada yang tersambung dan ada garis putus - putus. Perbedaan nya adalah garis tersambung berfungsi sebagai parent child sehingga apabila orang tua nya atau tabel master dihapus maka tabel anak nya atau child nya juga akan dihapus yang sering disebut dengan identifying relationship. Berbeda dengan garis putus - putus, jika master tabel dihapus maka child tabel tidak akan dihapus.

Dari tabel diatas kita bisa melihat bahwa jika tabel penjualan dihapus maka secara otomatis si tabel penjualan detail akan dihapus, berbeda dengan tabel barang, jika tabel barang dihapus maka tabel penjualan detail tidak dihapus.

Implementasi Pada H2 Database

H2 Database adalah salah satu dbms yang bisa kita gunakan sebagai database server maupun embedded database dan ditulis dengan menggunakan bahasa pemrograman java.

Pada tutorial ini, kita akan menggunakan h2 database untuk membuat relasi dengan menggunakan foreign key. Silahkan download h2 database di h2 database. Penulis mendownload file binary yang ada pada bagian Maven (Binary, Javadoc, and Source), kemudian jalankan perintah berikut.

java -jar h2-1.4.191.jar

Maka secara otomatis browser akan terbuka dan melakukan akses web h2 database yang akan kita gunakan. Kemudian ubah jdbc url seperti berikut

jdbc:h2:~/database/belajar_h2

Kemudian klik connect, secara otomatis h2 database akan membuat database dengan nama belajar_h2.mv.db di dalam folder database. Tampilan web h2 database yang akan tampil seperti berikut.

Screenshot from 2016-03-26 14:38:54.png

Langkah selanjutnya, untuk membuat tabel barang, silahkan jalankan perintah berikut pada web h2 database.

CREATE TABLE IF NOT EXISTS tb_barang(
    id_barang VARCHAR(150) NOT NULL PRIMARY KEY,
    nama_barang VARCHAR(45) NOT NULL,
    jenis_barang VARCHAR(45) NOT NULL,
    tanggal_kadaluarsa DATE NOT NULL,
    harga_satuan_barang DECIMAL(10) NOT NULL,
    jumlah_tersedia_barang INT(10) NOT NULL
);

Kemudian untuk tabel penjualan silahkan jalankan perintah berikut.

CREATE TABLE IF NOT EXISTS tb_penjualan(
    kode_transaksi_penjualan VARCHAR(150) NOT NULL PRIMARY KEY,
    tanggal_transaksi DATE NOT NULL,
    nama_pembeli VARCHAR(45) NOT NULL,
    total_harga DECIMAL(10) NOT NULL
);

Langkah selanjutnya adalah membuat tabel penjualan detail, silahkan jalankan perintah berikut.

CREATE TABLE IF NOT EXISTS tb_penjualan_detail(
    kode_transaksi_penjualan_detail VARCHAR(150) NOT NULL PRIMARY KEY,
    jumlah_barang INT(10) NOT NULL,
    total_harga_per_barang DECIMAL(10) NOT NULL,
    kode_transaksi_penjualan VARCHAR(150) NOT NULL,
    id_barang VARCHAR(150) NOT NULL,
    FOREIGN KEY(kode_transaksi_penjualan) REFERENCES tb_penjualan(kode_transaksi_penjualan) ON DELETE CASCADE ON UPDATE CASCADE,
    FOREIGN KEY(id_barang) REFERENCES tb_barang(id_barang)
);

Untuk dapat mengenerate ERD dari tabel yang telah dibuat maka kita akan menggunakan Execute Query. Silahkan download aplikasi tersebut, jika sudah langsung buka aplikasi tersebut. Silahkan lakukan konfigurasi driver h2 database, setelah selesai, lakukan konfigurasi seperti berikut.

Screenshot from 2016-03-26 15:46:35.png

Lalu klik connect, silahkan klik nama databasenya kemudian pilih menu database dan pilih generate ERD lalu pilih map existing database maka akan muncul seperti berikut.

Screenshot from 2016-03-26 15:50:17.png

Kemudian pilih schema menjadi public, lalu pilih semua tabel dan pilih select all, maka outputnya akan seperti berikut.

Screenshot from 2016-03-26 16:03:03.png

Setelah selesai, silahkan klik generate. berikut adalah output yang dihasilkan.

Screenshot from 2016-03-26 16:09:24.png

Sekian artikel mengenai belajar membuat foreign key pada h2 database dan terima kasih :).