Download PERSISTENCE LAYER DENGAN iBATIS

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
www.tobuku.com
PERSISTENCE LAYER DENGAN iBATIS
Tingkat:
Desember 2009
Oleh : Feri Djuandi
√
Pemula
Menengah
Mahir
Apakah iBATIS itu?
Secara umum iBATIS bisa dijelaskan sebagai sebuah persistence framework yang
mengotomatisasi penjembatanan atau pemetaan (mapping) antara database SQL dan objekobjek di dalam Java. Definisi ini akan sangat membingungkan terutama bagi seseorang yang
tidak pernah mengenal iBATIS sebelumnya. Tidak perlu khawatir, mari kita pahami satu-per satu
dimulai dari istilah persistence. Pada sebuah sistem aplikasi client-server dengan arsitektur
three-tier dikenal tiga buah lapisan (layer) yang disebut sebagai presentasion, business logic dan
data. Lapisan-lapisan ini tentunya bukan sesuatu yang asing bagi banyak programmer sehingga
tidak perlu banyak dijelaskan di sini. Ilustrasi dari lapisan-lapisan ini diperlihatkan pada gambar
di bawah.
PRESENTASION
BUSINESS LOGIC
DATA
Gambar 1.
Seiring dengan berkembangnya evolusi pemrograman dan ditemukannya teknik-teknik yang
baru yang berdasarkan pengalaman diakui dapat meningkatkan efisiensi serta kemudahan maka
diperkenalkanlah sebuah lapisan persistence yang berada di antara business logic dan data
sehingga yang semula kedua lapisan itu langsung berinteraksi maka sekarang ada jembatan di
tengah-tengahnya yang mengatur komunikasi keduanya secara tidak langsung
PRESENTASION
DATA
PERSISTENCE LAYER
• Abstraction Layer
• Persistence Framework
• Driver/Interface
BUSINESS LOGIC
Gambar 2.
JVA-FD-09004 – PERSISTENCE LAYER DENGAN IBATIS
1
www.tobuku.com
Perlu dipahami bahwa persistence layer adalah konsep yang umum pada pengembangan
sebuah aplikasi dan tidak terkait secara spesifik dengan sebuah teknologi atau produk tertentu.
Selain diaplikasikan pada lingkungan Java, persistence layer juga biasa diterapkan pada platform
yang lain seperti .NET.
Sebuah persistence layer bekerja dengan hal-hal yang berhubungan dengan persisting yaitu
penyimpanan (storing) dan pembacaan (retrieving) data ke/dari database. Tujuan yang paling
mendasar dari keberadaan sebuah persistence layer adalah:
•
Mengambil alih pekerjaan-pekerjaan yang berkaitan dengan persisting dari lapisan
business logic (misalnya perintah SELECT, INSERT dan UPDATE) sehingga business logic
bisa sungguh-sungguh fokus dengan rangkaian-rangkaian program yang berhubungan
dengan logika bisnis, aturan dan aliran program dari aplikasi yang bersangkutan tanpa
perlu dipusingkan dengan detail dari perintah-perintah SQL dari database. Dengan
demikian, business logic menjadi bebas dan tidak tergantung dengan tipe atau platform
database apapun yang digunakan.
•
Memisahkan secara jelas antara kode program dengan perintah-perintah SQL dengan
cara mengeluarkan semua perintah operasi database dari business logic. Tujuannya
adalah untuk menghindari program yang campur aduk antara kode program dari aplikasi
dan perintah-perintah SQL. Hal ini sangat penting untuk kerapihan dan kemudahan
dalam memelihara kode program. Dengan demikian embedded SQL atau inline SQL
(perintah-perintah SQL yang berbaur dengan kode program) adalah sesuatu yang ingin
dihindari oleh persistence framework.
Merujuk pada gambar 2 di atas, tampak bahwa lapisan persistence terbagi menjadi tiga bagian
dengan masing-masing fungsi sebagai berikut:
1. Abstraction Layer. Berfungsi sebagai antar muka bagi lapisan persistence agar lapisan
business logic dapat berinteraksi dengannya. Bagian inilah yang akan dibahas pada
artikel ini.
2. Persistence Framework, dalam hal ini adalah iBATIS itu sendiri. Pada prakteknya iBATIS
adalah sebuah library (file JAR) yang diasosiasikan dengan sebuah project Java sehingga
class-class di dalam iBATIS dapat digunakan.
3. Driver/Interface. Yang dimaksud driver disini adalah antar muka untuk mengakses
database. Driver database yang digunakan dalam pemrograman Java adalah JDBC.
Jika Anda tergolong baru dalam menggunakan JDBC, silakan membaca artikel lain yang berjudul
“MENGAKSES DATABASE DENGAN JDBC”.
Selain iBATIS, persistence framework lainnya yang cukup populer adalah Hybernate. Hybernate
dikenal sebagai sebuah perkakas Object/Relation Mapping (O/RM) yang melakukan pemetaan
antara objek-objek (class Java) dengan table-table di dalam database secara langsung dimana
property-property dari sebuah class harus sama dengan kolom-kolom table yang bersangkutan.
Itu sebabnya pemetaan struktur antara objek dan table harus sama persis.
-2-
www.tobuku.com
Class Person
identifier
firstName
lastName
middleName
hairColor
height
weight
Table PERSON
Pemetaan langsung.
Class Person harus klop dengan
table PERSON
ID
FIRST_NAME
LAST_NAME
MIDDLE_NAME
HAIR_COLOR
HEIGHT
WEIGHT
Gambar 3.
Berbeda dengan Hybernate, iBATIS bukanlah sebuah perkakas O/RM melainkan sebuah
perkakas Query Mapping karena iBATIS tidak memetakan struktur table dengan sebuah class
secara langsung, namun melalui perintah-perintah SQL (SELECT, INSERT, UPDATE atau DELETE).
Pemetaan pada iBATIS memiliki fleksibilitas tinggi, selain itu programmer memiliki kontrol lebih
besar terhadap perintah-perintah SQL dan kebebasan lebih dalam kustomisasi.
Class Person
identifier
firstName
lastName
middleName
hairColor
height
weight
SELECT
ID as identifier
FIRST_NAME as firstName
LAST_NAME as lastName
MIDDLE_NAME as middleName
HAIR_COLOR as hairColor
HEIGHT as height
WEIGHT as weight
FROM PERSON
WHERE ID=#identifier#
Table PERSON
ID
FIRST_NAME
LAST_NAME
MIDDLE_NAME
HAIR_COLOR
HEIGHT
WEIGHT
Gambar 4.
Masing-masing pendekatan antara Hybernate dan iBATIS memiliki kelebihan dan kekurangan,
namun keduanya memiliki fungsi yang sama sebagai sebuah persistence layer.
-3-
www.tobuku.com
Persiapan Sebelum Memulai
Sebelum melanjutkan pembahasan iBATIS, silakan mempersiapkan hal-hal sebagai berikut yang
akan dibutuhkan selama penjelasan di dalam artikel ini:
1. Library iBATIS
Library iBATIS tersedia secara gratis dengan cara men-download-nya melalui situs web:
http://ibatis.apache.org/
Pada artikel ini versi iBATIS yang digunakan adalah iBATIS Java 2.3.4. Anda memiliki kebebasan
untuk menggunakan versi yang lebih baru. Kecuali ada hal-hal yang disebutkan secara khusus,
seharusnya contoh-contoh program di dalam artikel ini dapat berjalan dengan baik pada iBATIS
versi yang lebih baru.
2. JDBC driver
Database yang digunakan pada contoh-contoh program adalah Ms SQL Server. Ada sejumlah
JDBC driver untuk Ms SQL Server yang tersedia di pasaran, namun salah satu yang cukup baik
dan teruji dalam penggunaannya adalah jTDS. JDBC driver ini dapat diperoleh secara gratis dari
situs web:
http://jtds.sourceforge.net/
jDTS yang dipergunakan dalam contoh program ini adalah versi 1.2.4, namun sekali lagi - Anda
memiliki kebebasan untuk menggunakan versi yang lebih baru.
-4-
www.tobuku.com
Mengasosiasikan Project dengan iBATIS Framework
Setelah langkah-langkah persiapan di atas selesai dilakukan, maka kita bisa mulai menggunakan
iBATIS.
1. Jalankan Eclipse dan buatlah sebuah Java Project.
2.
Beri nama project tersebut sebagai persist-exercise01. Klik tombol Finish.
-5-
www.tobuku.com
3. Dengan menggunakan Windows Explorer, buatlah sebuah sub-folder di dalam folder
project tersebut dan beri nama lib.
4. Copy-kan file-file library iBATIS dan jTDS ke dalam sub-folder tersebut. Pada contoh ini
file yang dimaksud adalah:
•
ibatis-2.3.4.726.jar
•
jtds-1.2.2.jar
Nama file-file di atas akan berbeda tergantung dari versi library yang dipergunakan.
5. Kembali kepada Eclipse, klik kanan pada folder project persist-exercise01 dan atur
konfigurasi Build Path.
-6-
www.tobuku.com
6. Klik tombol “Add External JARs” dan tambahkan kedua file JAR yang ada di dalam folder
lib tadi.
7. Setelah file-file library ditambahkan, tekan tombol F5 untuk me-refresh tampilan pada
Package Explorer. Seperti diperlihatkan pada gambar di bawah ini, tampak bahwa kedua
library telah diasosiasikan dengan project ini.
Anda telah selesai mengaosiasikan sebuah project dengan iBATIS Framework. Silakan ikuti
uraian berikutnya untuk melihat bagaimana framework ini dipergunakan.
-7-
www.tobuku.com
Program Sederhana dengan iBATIS Framework
Untuk alasan kemudahan dalam memahami penggunaan iBATIS bagi pemula, maka uraian ini
dibagi menjadi empat tahap sebagai berikut:
1. Menentukan konfigurasi koneksi database
2. Membuat model
3. Membuat pemetaan SQL dari table dengan model
4. Membuat implementasi
Menentukan konfigurasi koneksi database
Di dalam membuat sebuah aplikasi berbasis database, tidak peduli aplikasi tersebut besar atau
kecil, sederhana atau kompleks – selalu ada satu hal yang sama: membuat koneksi ke database.
Hal tersebut juga berlaku pada iBATIS. Langkah pertama yang harus dilakukan adalah
menentukan parameter-parameter koneksi yang digunakan untuk terhubung ke sebuah
database.
1. Jalankan Eclipse dan buat sebuah package melalui menu New Package. Beri nama
sebagai org.exercise01.persist.dao.
-8-
www.tobuku.com
2. Buat sebuah file XML di dalam package di atas melalui menu New Other, kemudian
pilih XML.
Beri nama file XML tersebut sebagai SqlMapConfig.xml.
-9-
www.tobuku.com
3. Salin kode program di bawah ini ke dalam file tersebut. Kode program ini tentunya harus dimodifikasi untuk disesuaikan dengan
kebutuhan Anda. Seperti yang dijelaskan sebelumnya, pembahasan artikel ini menggunakan database SQL Server itu sebabnya JDBC
driver yang digunakan adalah jTDS (lihat property JDBC.Driver pada program di bawah). Anda memiliki kebebasan untuk menggunakan
database yang lain seperti MySQL atau Oracle, namun pastikan menggunakan JDBC driver yang sesuai pula.
Kode program 1 . SqlMapConfig.xml.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<transactionManager type="JDBC" commitRequired="false">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="net.sourceforge.jtds.jdbc.Driver" />
<property name="JDBC.ConnectionURL"
value="jdbc:jtds:sqlserver://127.0.0.1/Northwind" />
<property name="JDBC.Username" value="sa" />
<property name="JDBC.Password" value="" />
</dataSource>
</transactionManager>
<sqlMap resource="org/exercise01/persist/dao/Employee.xml" />
</sqlMapConfig>
Selanjutnya property JDBC.ConnectionURL berisi nama server dan database. Hal ini pun harus disesuaikan JDBC driver yang digunakan
karena masing-masing driver memiliki aturan penulisan parameter yang berbeda-beda. Pada contoh ini server yang digunakan adalah
komputer lokal dimana alamat IP nya ditandai dengan 127.0.0.1 yang merupakan standar IP lokal. Sementara itu, database SQL Server
yang digunakan bernama Northwind.
Akhirnya, property resource pada bagian sqlMap merujuk pada definisi pemetaan SQL yang akan dijelaskan pada bagian berikutnya
beberapa saat lagi. Untuk sekarang cukup simpan semua perubahan yang dilakukan pada file tersebut.
-10-
www.tobuku.com
4. Buat sebuah class di dalam package yang sama melalui menu New Class. Beri nama class tersebut sebagai DaoFactory dan salin kode
program di bawah ini ke dalamnya.
Kode program 2. DaoFactory.java.
package org.exercise01.persist.dao;
import java.io.Reader;
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
public class DaoFactory {
private static SqlMapClient instance;
public static SqlMapClient getSqlMapClient() throws Exception
{
if(instance == null) {
try {
Reader
reader = Resources.getResourceAsReader
("org/exercise01/persist/dao/SqlMapConfig.xml");
instance = SqlMapClientBuilder.buildSqlMapClient(reader);
}
catch (Exception ex) {
throw ex;
}
}
return instance;
}
}
Kode program di atas cukup standar dan tidak perlu diubah (kecuali mungkin nama package pada baris paling atas), oleh karena itu
nantinya file Java dari class ini dapat disimpan dan digunakan untuk aplikasi-aplikasi yang lain.
-11-
Membuat Model
Model yang dimaksud dalam konteks ini adalah model entitas yang dikenal di dalam aplikasi, misalnya
entitas Employee. Contoh entitas lainnya adalah Customer, Product, Order dan sebagainya. Selain
dikenal sebagai objek di dalam kode program, entitas ini biasanya dikenal juga sebagai table di dalam
database. Dengan demikian, struktur model biasanya tidak jauh berbeda dengan struktur table yang
bersangkutan, walaupun strukturnya tidak perlu sama persis (inilah salah satu keunggulan iBATIS
dibandingkan Hybernate).
1. Jalankan Eclipse dan buat sebuah package melalui menu New Package. Beri nama sebagai
org.exercise01.persist.model.
2. Di dalam package tersebut, buat sebuah class dan beri nama sebagai Employee.java.
3. Salin kode program di bawah ini ke dalam class tersebut. Perhatikan bahwa property dari class
ini analogi dengan kolom-kolom di dalam table Employee.
Kode program 3. Employee.java.
package org.exercise01.persist.model;
import java.sql.Timestamp;
public class Employee {
private int
employeeId;
private String
lastName;
private String
firstName;
private String
title;
private String
titleOfCourtesy;
private Timestamp birthDate;
private Timestamp hireDate;
private String
address;
private String
city;
private String
region;
private String
postalCode;
private String
country;
private String
homePhone;
private String
extension;
private String
notes;
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
-12-
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitleOfCourtesy() {
return titleOfCourtesy;
}
public void setTitleOfCourtesy(String titleOfCourtesy) {
this.titleOfCourtesy = titleOfCourtesy;
}
public Timestamp getBirthDate() {
return birthDate;
}
public void setBirthDate(Timestamp birthDate) {
this.birthDate = birthDate;
}
public Timestamp getHireDate() {
return hireDate;
}
public void setHireDate(Timestamp hireDate) {
this.hireDate = hireDate;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
-13-
public String getHomePhone() {
return homePhone;
}
public void setHomePhone(String homePhone) {
this.homePhone = homePhone;
}
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
}
Di dalam class tersebut tidak ada method lain kecuali method getter dan setter untuk setiap property.
-14-
Membuat Pemetaan SQL dari Table dengan Model
Bagian ini adalah bagian yang terpenting karena inti dari iBATIS Framework adalah pemetaan SQL (SQL
mapping).
Ilustrasi mengenai SQL mapping diperlihatkan pada gambar di bawah ini. Perhatikan bagian bawah dari
gambar tersebut, tampak bahwa SQL map ada di tengah-tengah antara table-table database dan modelmodel (class Java) sekaligus menjadi acuan dari SqlMapConfig.xml sehingga jelas bahwa SQL map adalah
sentral dari semuanya. Itulah sebabnya sebagian besar waktu yang dicurahkan oleh programmer di
dalam menggunakan iBATIS framework adalah bekerja dengan SQL map.
BUSINESS LOGIC
PERSISTENCE LAYER
ABSTRACTION LAYER
Implementasi
DaoFactory.java
SqlMapConfig.xml
SQL Map
DATA
CUSTOMER
EMPLOYEE
ORDER
PRODUCT
...
JDBC
Model
Customer.xml
Employee.xml
Order. xml
Product.xml
...
Customer.java
Employee. java
Order. java
Product. java
...
iBATIS FRAMEWORK
Ingat bahwa SQL map harus dibuat untuk setiap entitas.
-15-
Sekarang kita lihat bagaimana membuat sebuah SQL map.
1. Jalankan Eclipse dan buat sebuah file XML di dalam package org.exercise01.persist.dao melalui
menu New Other, kemudian pilih XML. Beri nama file tersebut sebagai Employee.xml.]
2. Salin kode program di bawah ini ke dalam file XML tersebut dan simpan semua perubahan.
Kode program 4. Employee.xml.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Employee">
<select id="getSimpleEmployee"
resultClass="org.exercise01.persist.model.Employee">
SELECT EmployeeID AS employeeId
,LastName AS lastName
,FirstName AS firstName
,Title AS title
,TitleOfCourtesy AS titleOfCourtesy
,BirthDate AS birthDate
,HireDate AS hireDate
,Address AS address
,City AS city
,Region AS region
,PostalCode AS postalCode
,Country AS country
,HomePhone AS homePhone
,Extension AS extension
FROM Employees
</select>
</sqlMap>
Sekarang kita akan pahami bagian-bagian dari SQL map di atas. Kode program tersebut adalah bentuk
SQL map yang paling sederhana karena saat ini fungsinya hanya untuk membaca data dan itu pun
menggunakan perintah SELECT dasar yang statis tanpa diikuti kondisi WHERE dan parameter-parameter
apapun. Pada tingkat lanjut, SQL map mampu membentuk perintah SQL yang dinamis. Tahap itu akan
dibicarakan nanti setelah konsep dasarnya bisa dipahami. Perhatikan bahwa SQL map ini membaca data
dari table Employees.
Setiap SQL map memiliki sebuah pengenal yang unik atau ID, dalam contoh di atas adalah
getSimpleEmployee. Selanjutnya SQL map ini dipetakan dengan sebuah model yang strukturnya
bersesuaian, dalam hal ini adalah class Employee yang ada di dalam package
org.exercise01.persist.model. Apakah Anda sudah mulai memahami cara kerjanya?
Jika di dalam sebuah aplikasi terdapat beberapa entitas, maka SQL mapping harus dibuat untuk setiap
entitas tersebut – sebuah SQL map untuk setiap table dan sebuah class.
-16-
Membuat Implementasi
Bagian terakhir yang dilakukan di dalam persistence layer adalah membuat implementasi dari SQL map.
Perhatikan dari gambar sebelumnya bahwa business logic tidak langsung mengakses SQL map tetapi
melalui sebuah implementasi. Artinya sebuah implementasi menjadi kulit terluar atau antar muka bagi
business logic untuk berinteraksi dengan persistence layer.
1. Jalankan Eclipse dan buat sebuah package melalui menu New Package. Beri nama sebagai
org.exercise01.persist.impl.
2. Di dalam package tersebut, buat sebuah class dan beri nama sebagai EmployeeSimpleImpl.java.
3. Salin kode program di bawah ini ke dalam class tersebut.
Kode program 5. EmployeeSimpleImpl.java.
package org.exercise01.persist.impl;
import
import
import
import
org.exercise01.persist.dao.*;
org.exercise01.persist.model.*;
com.ibatis.sqlmap.client.SqlMapClient;
java.util.List;
public class EmployeeSimpleImpl {
private static EmployeeSimpleImpl instance;
private SqlMapClient mapper;
public EmployeeSimpleImpl() throws Exception
{
mapper = DaoFactory.getSqlMapClient();
}
public static EmployeeSimpleImpl getInstance() throws Exception
{
if(instance == null)
instance = new EmployeeSimpleImpl();
return instance;
}
@SuppressWarnings("unchecked")
public List<Employee> retrive()
throws IllegalArgumentException, Exception
{
try {
return mapper.queryForList("getSimpleEmployee",
null);
}
catch (Exception e) {
throw e;
}
}
}
Di dalam class EmployeeSimpleImpl terdapat dua buah method yaitu getInstance untuk mendapatkan
referensi sebuah instance dari class yang bersangkutan; dan retrive untuk mendapatkan rangkaian (List)
dari objek Employee sebagai hasil eksekusi perintah SELECT melalui pemanggilan SQL map dengan ID
getSimpleEmployee.
-17-
Tentunya kemampuan sebuah implementasi tidak terbatas hanya untuk membaca data. Ia bisa
dikembangkan dengan menambahkan method-method lain misalnya update (untuk UPDATE <table>),
delete (untuk DELETE <table>), create (untuk INSERT <table>), execute (untuk EXEC
<stored_procedure>) dan sebagainya.
-18-
Memanggil Persistence Layer dari Business Logic
Sebagai akhir pembahasan dari bagian ini, akan diperlihatkan kode program dari business logic saat ia berinteraksi dengan persistence layer yang
baru saja dibuat tadi.
1. Jalankan Eclipse dan buat sebuah package melalui menu New Package. Beri nama sebagai org.exercise01.persist.
2. Di dalam package tersebut, buat sebuah class dan beri nama sebagai PersistExercise01.java.
3. Salin kode program di bawah ini ke dalam class tersebut.
Kode program 5. PersistExercise01.java.
package org.exercise01.persist;
import java.util.*;
import org.exercise01.persist.impl.*;
import org.exercise01.persist.model.*;
public class PersistExercise01 {
/**
* @param args
*/
public static void main(String[] args) {
try {
EmployeeSimpleImpl impl = new EmployeeSimpleImpl();
List<Employee> listOfEmployee = impl.retrive();
System.out.println("=========================================================");
System.out.println("Employee ID
First Name
Last Name");
System.out.println("=========================================================");
for(Iterator<Employee> itOfEmployee = listOfEmployee.iterator();
itOfEmployee.hasNext();)
{
Employee employee = itOfEmployee.next();
System.out.print(employee.getEmployeeId() + "\t\t");
System.out.print(employee.getFirstName() + "\t\t\t");
System.out.println(employee.getLastName());
}
System.out.println("=========================================================");
-19-
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Inti dari kode program di atas yang berhubungan dengan pemanggilan implementasi dari persistence layer ada pada dua baris berikut ini:
...
EmployeeSimpleImpl impl = new EmployeeSimpleImpl();
List<Employee> listOfEmployee = impl.retrive();
...
Baris-baris
baris kode program berikutnya hanyalah untuk menampilkan hasilnya (presentation).. Cukup mudah dipahami, bukan?
-20-