Mencari Isi Tabel Dengan simple-jpa 0.5


Salah satu fitur menarik di simple-jpa 0.5 adalah perintah simple-jpa-console.  Perintah ini memungkinkan saya untuk mengerjakan kode program yang memakai simple-jpa secara interaktif.   Seorang programmer JavaScript mungkin sudah terbiasa mengerjakan cuplikan kode program di browser.   Groovy juga bahasa dinamis, sehingga fitur serupa bukanlah hal mustahil di Groovy.  Dengan menggunakan fasilitas simple-jpa console, saya juga dapat mengerjakan potongan kode program Groovy dan langsung memperoleh hasilnya tanpa harus menjalankan program.   Hal ini sangat berguna untuk mendemokan kode program yang memakai simple-jpa atau sekedar mencoba finders yang ada.

Untuk menampilkan simple-jpa console, saya perlumemberikan perintah berikut ini:

griffon simple-jpa-console
Tampilan simple-jpa console

Tampilan simple-jpa console

Console tersebut adalah sebuah GroovyConsole biasa yang dilengkapi dengan sebuah menu tambahan, yaitu menu simple-jpa.   Bila saya memilih menu simple-jpa, MVC Groups, saya akan memperoleh daftar MVC Group yang telah didefinisikan, seperti yang terlihat pada gambar berikut ini:

Tampilan MVC Groups

Tampilan Daftar MVCGroups

Kolom Alive? menunjukkan apakah MVC Group tersebut sudah aktif atau belum.   Pada saat dijalankan, hanya sebuah MVC Group yang aktif, yaitu MVC Group didefinisikan sebagai startup.   Bila terdapat sebuah MVC Group dengan nama mainGroup yang sudah aktif, maka saya dapat mengakses MVC-nya melalui variabel bernama mainGroupController, mainGroupView dan mainGroupModel.   Saya juga dapat mengakses instance dari GriffonApplication melalui sebuah variabel bernama app.

Untuk melihat daftar variabel yang dapat dipakai, saya dapat memilih menu Script, Inspect Variables.   Akan muncul dialog seperti pada gambar berikut ini:

Melihat daftar variable

Melihat daftar variable

Seluruh controller (dari MVCGroup) yang memakai simple-jpa akan secara otomatis memiliki method-method untuk bekerja dengan database.   Anggap saja controller juga berperan sebagai repository tetapi tidak dalam layer terpisah.   Sebuah controller juga tidak terbatas harus terikat pada domain class atau entity tertentu.   Seluruh controller yang ada dapat mengakses entity apa saja yang mereka butuhkan.

Sebagai contoh, saya mengetikkan kode program untuk menyimpan tiga object Sales (dengan asumsi saya telah membuat domain class ini sebelumnya melalui perintah create-domain-class) lalu menjalankannya dengan memilih menu Script, Run (atau menekan tombol Ctrl+R) seperti yang terlihat pada gambar berikut ini:

Menyimpan object ke database melalui simple-jpa console

Menyimpan object ke database melalui simple-jpa console

Bila saya memeriksa database, maka saya akan menemukan tiga record baru di tabel sales seperti yang terlihat pada gambar berikut ini:

Entity sudah tersimpan di tabel

Entity sudah tersimpan di tabel

Berikutnya, saya akan membuat kode program yang melakukan pencarian data.   Setiap controller di simple-jpa memiliki method findAllXXX() yang akan mengembalikan seluruh instance untuk domain class tersebut.   Juga ada method findXXXById() yang akan mengembalikan sebuah instance berdasarkan id atau ‘primary key’-nya.

Tanpa menutup simple-jpa console yang ada, saya menghapus kode program sebelumnya, lalu mengetik kode program baru dan menjalankannya sehingga memperoleh hasil seperti pada gambar berikut ini:

Mencari entitas dari tabel

Mencari entitas dari tabel

Terlihat bahwa proses mencari data dapat dilakukan dengan sangat mudah berkat simple-jpa.   Namun method findXXXById() kurang begitu berguna karena saya memakai surrogate primary key dimana id adalah primary key berupa nomor unik.   Nilai tersebut sangat jarang ditampilkan dan disajikan pada pengguna.  Saya lebih sering harus mencari berdasarkan atribut lain seperti nama.   Oleh sebab itu, saya lebih sering menggunakan dynamic finders.   Apa itu dynamic finders?   Dynamic finders adalah kumpulan method untuk men-query data dimana method-method tersebut memiliki nama dengan pola tertentu yang mewakili ekspresi pencarian.   Sebagai contoh, saya dapat mencari sales bernama 'Steven' dengan menggunakan kode program berikut ini:

import domain.Sales
def c = mainGroupController

Sales sales = c.findSalesByNama('Steven')
println "Sales bernama Steven tinggal di ${sales.alamat}"

sales = c.findSalesByNama('Snake')
if (!sales) println "Sales bernama Snake tidak ditemukan!"

// Output:
// Sales bernama Steven tinggal di Jl. Imam Bonjol
// Sales bernama Snake tidak ditemukan!

Dynamic finders juga mendukung operator seperti eq (sama dengan), ne (tidak sama dengan), gt (lebih dari), ge (lebih dari sama dengan), lt (kurang dari), le (kurang dari sama dengan), between (diantara), isNull, isNotNull, like dan notLike.   Berikut ini adalah contoh beberapa penggunaan dynamic finders yang melibatkan operator:

import domain.Sales
def c = mainGroupController

Sales sales = c.findSalesByNamaLike('S%')
println "Sales yang namanya diawali huruf S: $sales"

sales = c.findSalesByNomorTeleponIsNull()
println "Sales yang tidak memiliki nomor telepon: $sales"

sales = c.findSalesByIdLt(32769L)
println "Sales dengan id < 32769: $sales"

sales = c.findSalesByIdBetween(32768L, 32770L)
println "Sales dengan id antara 32768 dan 32700: $sales"

// Output:"
// Sales yang namanya diawali huruf S: Steven
// Sales yang tidak memiliki nomor telepon: null
// Sales dengan id < 32769: Steven
// Sales dengan id antara 32768 dan 32700: Steven

Pada contoh di atas, terlihat ada sebuah masalah yaitu method findXXXByXXX() selalu mengembalikan sebuah object  tunggal atau nilai null bila tidak ada object yang memenuhi ekspresi pencarian.  Bagaimana bila saya perlu mencari lebih dari satu object/entity?  Saya dapat menggunakan method findAllXXXByXXX() yang selalu mengembalikan sebuah List berisi satu atau lebih object, atau List kosong bila tidak ada object yang ditemukan.   Sebagai contoh, saya dapat mengubah kode program di atas menjadi seperti berikut ini:

import domain.Sales
def c = mainGroupController

def list = c.findAllSalesByIdBetween(32768L, 32770L)
println "Daftar sales dengan id diantara 32768 s/d 32770: $list"

list = c.findAllSalesByNomorTeleponIsNotNull()
println "Daftar sales yang memiliki nomor telepon: $list"

list = c.findAllSalesByAlamatLike('%Gajah Mada%')
println "Daftar sales yang tinggal di Gajah Mada: $list"

list = c.findAllSalesByAlamatLike('%Hayam Wuruk%')
println "Daftar sales yang tinggal di Hayam Wuruk: $list"

// Output:
// Daftar sales dengan id diantara 32768 s/d 32770: [Steven, David, Bruce]
// Daftar sales yang memiliki nomor telepon: [Steven, David, Bruce]
// Daftar sales yang tinggal di Gajah Mada: [David]
// Daftar sales yang tinggal di Hayam Wuruk: []

Bagaimana bila pencarian melibatkan lebih dari satu atribut?   Saya dapat menggabungkan dua atribut yang berbeda dengan menggunakan kata ‘Or’ atau ‘And’ di finders, seperti yang terlihat pada contoh berikut ini:

def c = mainGroupController

def s = c.findSalesByNamaLikeAndAlamatLike('%Steven%', '%Imam Bonjol%')
println "Sales bernama Steven dan tinggal di Imam Bonjol: $s"

s = c.findSalesByNamaLikeAndAlamatLike('%Steven%', '%Gajah Mada%')
println "Sales bernama Steven dan tinggal di Gajah Mada: $s"

def list = c.findAllSalesByNamaLikeOrAlamatLikeAndNomorTeleponLike('%Steven%', '%GajahMada%', '081%')
println "Daftar Sales dengan nama Steven atau yang tinggal di Gajah Mada dan nomor telepon diawali 081: $list"

// Output:
// Sales bernama Steven dan tinggal di Imam Bonjol: Steven
// Sales bernama Steven dan tinggal di Gajah Mada: null
// Daftar Sales dengan nama Steven atau yang tinggal di Gajah Mada dan nomor telepon diawali 081: [Steven]

Pada kode program di atas, terlihat bahwa semakin banyak atribut yang dilibatkan maka nama finders menjadi semakin panjang.   Tergantung pada selera developer, beberapa mungkin merasa ini tidak rapi.  Oleh sebab itu, sebagai alternatifnya, saya dapat menggunakan findXXXByDsl() dimana saya dapat menggunakan Dsl sederhana sebagai ekspresi pencarian.   Sebagai contoh, kode program dibawah ini menghasilkan output yang sama seperti di atas tetapi kali ini memakai Dsl:

def c = mainGroupController

def s = c.findSalesByDsl{
    nama like('%Steven%')
    and()
    alamat like('%Imam Bonjol%')
}
println "Sales bernama Steven dan tinggal di Imam Bonjol: $s"

s = c.findSalesByDsl {
    nama like('%Steven%')
    and()
    alamat like('%Gajah Mada%')
}
println "Sales bernama Steven dan tinggal di Gajah Mada: $s"

def list = c.findAllSalesByDsl {
    nama like('%Steven%')
    or()
    alamat like('%GajahMada%')
    and()
    nomorTelepon like('081%')
}
println "Daftar Sales dengan nama Steven atau yang tinggal di Gajah Mada dan nomor telepon diawali 081: $list"

Saya paling sering memanfaatkan findXXXByDsl() untuk membangun ekspresi pencarian secara dinamis dalam satu kali pemanggilan (hal tersebut tidak begitu rapi bila memakai dynamic finders).  Sebagai contoh, saya memiliki sebuah tampilan pencarian yang terlihat seperti pada gambar berikut ini:

View untuk melakukan pencarian

View untuk melakukan pencarian

Dengan menggunakan findXXXByDsl(), saya dapat membangun ekspresi pencarian dalam satu kali pemanggilan berdasarkan apa yang dipilih oleh pengguna:

...
// kode program ini berada didalam controller sehingga tidak perlu diawali
// nama controller seperti pada saat dipakai di simple-jpa console
...
List result = findAllFakturByDsl {
  if (nomorFakturSearch) {
     nomor like("%${nomorFakturSearch}%")
  }
  if (selectedKonsumen!=SEMUA_KONSUMEN) {
     and()
     konsumen eq(selectedKonsumen)
  }
  if (selectedSales!=SEMUA_SALES) {
     and()
     sales eq(selectedSales)
  }
  if (model.belumLunasSearch) {
     and()
     lunas eq(false)
  }
}
...

Pada seluruh contoh program di atas, terlihat bahwa cukup dengan sebuah controller apa saja, saya sudah dapat melakukan operasi database pada seluruh entitas yang ada.   Akan tetapi, terkadang saya perlu mengerjakan sebuah method yang telah didefinisikan di sebuah controller (di MVCGroup berbeda).   Sebelum dapat memakai sebuah MVCGroup, saya perlu mengaktifkannya terlebih dahulu.   Caranya adalah dengan memilih menu simple-jpa, MVC Groups, kemudian memberi tanda centang pada MVCGroup yang akan diaktifkan, seperti yang terlihat pada gambar berikut ini:

Mengaktifkan MVC Group

Mengaktifkan MVC Group

Setelah ini, saya akan memperoleh variabel baru yang dapat saya lihat dengan memilih menu Script, Inspect Variables seperti yang terlihat pada gambar berikut ini:

Variabel baru untuk MVC Group yang diaktifkan

Variabel baru untuk MVC Group yang diaktifkan

Sekarang, saya dapat mengerjakan method yang berada dalam controller tersebut melalui variabel yang ada, seperti yang terlihat pada gambar berikut ini:

Mengerjakan method milik sebuah controller

Mengerjakan method milik sebuah controller

Perihal Solid Snake
I'm nothing...

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: