19 November 2007

Menggunakan Property File dalam Java untuk Koneksi Database

Keputusan melakukan hardcode (menulis suatu nilai properti) langsung dalam aplikasi kita bukanlah sebuah keputusan yang bijak. Misalnya properti-properti yang berhubungan dengan database. Ketika suatu saat kita mencoba mengganti user atau password dalam database, maka secara otomatis kita juga harus membongkar kembali program kita untuk memperbaiki nilai user atau password. Sungguh suatu yang lumayan merepotkan dan makan waktu.

Di sini saya akan mencoba membuat sebuah program java yang menggunakan properti file sebagai settingan untuk koneksi ke database. Dalam properti file ini nilai-nilai yang mudah berubah seperti user, password, database url, nama database, dan lain-lain akan kita tulis dalam properti file ini, sehingga jika suatu kali ada perubahan dari segi settingan database kita tidak perlu lagi membongkar ulang program-program kita. Cukup hanya dengan mengganti nilai dalam properti file saja.
Langsung saja, Kita memerlukan dua class dan satu file dalam percobaan ini :

  1. Class yang berisi method untuk memanggil file konfigurasi.
  2. Class yang berisi program utama (main program).
  3. File properti yang berisi settingan database.

File pertama ConfigProperties.java


import java.util.Properties;
import java.io.*;


public final class ConfigProperties {
private static ConfigProperties instance;

private static String file_properties = null;
private static Properties ppty = null;

private ConfigProperties() {
// private constructor
}
public static ConfigProperties getInstance( String filename )
throws FileNotFoundException, IOException {

if( instance == null ) {

if ( null == ppty ) {
try {
System.out.println( "LOADING properties......" );

ppty = new Properties();
FileInputStream in = new FileInputStream( filename );
ppty.load( in );
in.close();

}
catch( FileNotFoundException e ) {
throw new FileNotFoundException(
"File - " + filename + " not found in the working directory" );
}
}
}

return instance;
}

/**
* Get the value of the property name.
*
* @param key the property name specified in the properties file.
*
* @return the value of the property name.
*/
static public String getProperty( String key ) {

String str = ppty.getProperty( key );
if ( null == str ) {
System.out.println(
"Warning: attempt to get an non-existant value in property file: " + key );
}

return str;
}
}


Pada file tersebut dapat kita perhatikan bahwa pertama kita mengimport 2 package langsung yaitu package java.io dan package
java.util


import java.util.Properties;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileInputStream;

Kemudian kita membuat satu method bernama getInstance yang mempunyai parameter String filename,
static  public String getProperty(String key) {
String str = ppty.getProperty(key);
if (null == str) {
System.out.println("Warning: "+
"attempt to get an non-existant value in "+
"property file:" + key);
}
return str;
}
}

dalam method ini kita meng-instansiasi class properties sebagai sebuah obyek baru dalam variable ppty, dimana variable ppty mempunyai tipe data turunan class properties


private  static Properties ppty = null;   //Variabel
// turunan dari Class Properties
ppty = new Properties(); //instansiasi class Properties

Kemudian kita mulai membaca file configuration yang diambil dari inputan parameter dengan menginstansiasi class FileInputStream untuk kemudian dilanjutkan dengan me-load filename tsb ke dalam variabel properties dengan menggunakan method load yang dimiliki oleh class properties tsb

FileInputStream in = new FileInputStream(filename);
// membaca filename dari inputan
// parameter class getInstance
ppty.load(in);
//me-load filename ke dalam Class Properties

Kita dapat melengkapi method getInstance ini dengan cara meletakkan pembacaan file dan loading filename ke dalam block try catch sebagai salah satu usaha kita untuk menjaga kalau-kalau filename yang akan dibaca tidak ada pada tempat yg telah ditentukan.
Selanjutnya kita buat satu method lagi dalam file Class ConfigProperties ini, dimana method ini akan membaca isi dari file yang telah diload. Method ini kita beri nama getProperty dengan parameter String key. Method ini akan mengembalikan nilai String pada penggunaannya nanti.

Dalam method ini kita dapat melihat bahwa jika key yang akan dibaca tidak ada dalam properti filenya maka kita tandai dengan cara memberi tahu user bahwa key tsb tidak exist dalam properti file.

Sampai disini sudah selesai kita membuat file ConfigProperties yang berguna untuk membaca file properties.
Untuk selanjutnya kita akan membuat main class (Kelas Utama) sebagai salah satu cara kita menguji class ConfigProperties yang kita buat di atas.

Kita mulai saja. Main class ini kita beri nama TestConnection.java. berikut penjelasannya:

Pertama kita import dulu package java standar yg kita butuhkan untuk berkomunikasi dengan database yaitu :

  • package java.sql.Connection
  • package java.sql.Driver
  • package java.sql.SQLException


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

Lalu kemudian kita mulai deklarasikan variable yg kita butuhkan:
private  static String db_driver = "db_driver";
private static String db_url = db_url";
private static String db_user = "db_user";
private static String db_pass = "db_pass";
private String sDbDriver;
private String sDbUrl;
private String sDbUser;
private String sDbPass;
private Connection dbConnection;


Keempat variabel yang pertama diatas merupakan variabel static dan variabel ini juga bersifat private dengan tujuan supaya variable ini tidak dapat diakses oleh class lain, karena static maka variabel ini langsung kita isi nilainya dengan string yang akan kita tuliskan ke dalam file configuration nantinya, yaitu “db_driver”, “db_url”, “db_user”, “db_pass”. Sementara keempat variabel kedua juga kita beri sifat private juga dengan tujuan agar variabel ini tidak dapat di akses oleh class lain yang sifatnya public, namun dia tidak static sehingga nanti bisa kita inisialisasi variabel ini. Apa sih bedanya sifat public dengan private? Pertanyaan ini akan saya jawab mungkin dalam tulisan saya berikutnya. Kita lanjutkan…Setelah selesai mendefinisikan variabel, kita akan membuat default constructor dari main class ini. Dimana default constructor ini nantinya akan memanggil sebuah method yang bernama init.

Dalam main class ini, sementara dalam method init ini kita akan menginisialisasikan variable sDbDriver, sDbUrl, sDbUser, sDbPass dengan mengambil nilai dari variable static yang didefinisikan sebelumnya.


public TesConnection() {
init();
}
public void init() {
//inisialisasi variabel
sDbDriver = ConfigProperties.getProperty(db_driver);
sDbUrl = ConfigProperties.getProperty(db_url);
sDbUser = ConfigProperties.getProperty(db_user);
sDbPass = ConfigProperties.getProperty(db_pass);
}

Sekarang kita akan membuat method utama (Main Method) dari class ini. Main method ini secara berurutan akan memanggil

  1. File fisik properti, dalam contoh ini file properti nya akan kita letakkan dalam folder config.
  2. Kita akan mencoba connect ke database.
  3. putuskan koneksi dari database
oleh karena kita akan coba melakukan koneksi ke database, agar lebih rapih kita letakkan code koneksi ke database ini dalam sebuah method dengan nama method connectDB, sehingga pada penggunaannya tinggal kita panggil saja method tsb. Berikut codenya



Dapat kita lihat pada method ini kita menginisialisasi driver database, kemudian melakukan koneksi diwakili dengan variabel dbConnection didalam block try catch.Demikian juga dengan perintah putuskan koneksi dari database kita juga buat saja dalam satu method yang nantinya tinggal kita panggil dalam method utama, berikut code method untuk melakukan pemutusan dari database.
private void disconnectDB() {
System.out.println("Trying to Disconnect DB....");
if(dbConnection !=null){
try{
dbConnection.close();
System.out.println("Disconnecting DB Done..");

}catch(SQLException e){
System.out.println("Exception in Disconnecting DB");
}
}
}
Dalam method ini simple saja hal-hal yang akan kita lakukan yaitu jika dbConnection nya ada atau tidak sama dengan null maka putuskanlah.

Nah sekarang tibalah saatnya kita membuat method utama dari class ini, seperti yang kita tadi rencanakan bahwa method utama dari kelas ini berisi tiga langkah yaitu panggil file fisik configurationnya, lakukan koneksi ke database dan terkahir putuskan hubungan dari database.

Untuk memanggil file fisik dari configuration kita cukup meng-instansiasi class pertama yang kita buat yaitu class ConfigProperties dengan cara meletakkannya di dalam blok try catch. Berikut codenya keseluruhan dalam method utama.


public static void main(String[] args) {
try {
ConfigProperties.getInstance
("config/database_conn.properties");
} catch (Exception e) {
System.out.println("Exception in getProperties=" +
e.getMessage());
}
//initialize Class
TesConnection test = new TesConnection();
//panggil method connectDB
test.connectDB();
// panggil method disconnect
test.disconnectDB();
}
Jika kita gabungkan semua method-method tsb dalam suatu class utama maka akan seperti ini jadinya:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
* Created by IntelliJ IDEA.
* User: Mojo
* Date: Nov 18, 2007
* Time: 7:27:09 PM
* To change this template use File | Settings
* | File Templates.
*/
public class TesConnection {
private static String db_driver = "db_driver";
private static String db_url = "db_url";
private static String db_user = "db_user";
private static String db_pass = "db_pass";

private String sDbDriver;
private String sDbUrl ;
private String sDbUser;
private String sDbPass;
private Connection dbConnection;

public TesConnection() {
init();
}

public void init() {
//inisialisasi variabel
sDbDriver = ConfigProperties.getProperty(db_driver);
sDbUrl = ConfigProperties.getProperty(db_url);
sDbUser = ConfigProperties.getProperty(db_user);
sDbPass = ConfigProperties.getProperty(db_pass);
}
public static void main(String[] args) {
try {
ConfigProperties.getInstance("config"+
"/database_conn.properties");
} catch (Exception e) {
System.out.println("Exception in getProperties=" +
e.getMessage());
}

//initialize Class
TesConnection test = new TesConnection();

//try to Connect
test.connectDB();

//disconnect
test.disconnectDB();

}
private void disconnectDB() {
System.out.println("Trying to Disconnect DB....");
if(dbConnection !=null){
try{
dbConnection.close();
System.out.println("Disconnecting DB Done..");

}catch(SQLException e){
System.out.println("Exception in Disconnecting DB");
}
}


}

private void connectDB() {

System.out.println("Trying to Connect to DataBase...");
try {
Class.forName(sDbDriver);
dbConnection =
DriverManager.getConnection(sDbUrl,sDbUser,sDbPass);
System.out.println(
"Connecting Database Done....");
} catch (SQLException sqle) {
System.out.println("SQLException in ConnectDB=" +
sqle.getMessage());
} catch(Exception e){
System.out.println("Exception in ConnectDB = " +
e.getMessage());

}

}
}
Nah sekarang yg akan kita buat adalah file terakhir yaitu file configurationnya dimana file ini hanya terdiri dari baris-baris yang menjadi properti key yang natinya akan dibaca oleh class ConfigProperties, isi baris tersebut adalah :
  1. db_driver
  2. db_url
  3. db_user
  4. db_pass
Nilai-nilai yang ada dalam File configurasi inilah yg bisa kita ganti-ganti sesuai dengan setting database yang ada pada kita. Berikut isi dari File database_conn.properties
db_url=jdbc:mysql://localhost/test_doang?autoReconnect=true
db_user=root
db_pass=root123
db_driver=com.mysql.jdbc.Driver
Dalam file configuration ini kita bisa lihat bahwa beberapa settingan database kita simpan disini sehingga sewaktu-waktu nanti ada yang berubah dari settingan database tsb, kita hanya merubah nilai-nilai dalama file database_conn.properties ini saja tanpa harus membongkar seluruh aplikasi yang sudah kita compile.
Catatan jangan lupa menambahkan library mysql-connector dalam project ini dan juga menambahkan variable class mysql-connector dalam setting environment Operating System komputer kita ketika kita akan mendeploy aplikasi ini.


Semoga Bermanfaat

josescalia

15 comments:

agus beka said...

Ampun pak .. pusing wa liat coding mulu .. hehehe .. seep cup ada bakat loe jadi penulis dan pengajar ..salut bro

Anonymous said...

Wah, keren, tpi pusing,o ya mas, gmana kalau bwat artikel cara ngeprint file dengan menggunakan java, soalnya aku cari kmana2 kok gak ada2 ya, pa gak ada yang butuh ngeprint ya, kasian kan file nya udah di buat tapi kok gak di print sekalian...
he...he....

JoseScalia said...

Quote "Wah, keren, tpi pusing,o ya mas, gmana kalau bwat artikel cara ngeprint file dengan menggunakan java, soalnya aku cari kmana2 kok gak ada2 ya, pa gak ada yang butuh ngeprint ya, kasian kan file nya udah di buat tapi kok gak di print sekalian...
he...he...."

Terima kasih atas usulannya..nanti saya akan coba buat artikelnya..tapi sebagai masukan, saya memang jarang menggunakan fasilitas print menggunakan java, biasanya saya mengkonversi dalam format file lain, sehingga hasil dari file bisa di printout menggunakan program lain..

Thnks

Erwa_Cool said...

Bang jose cool banget codingnya tapi ane masih bingung ama file database_conn.properties, ne file bentuknya apa(extentionnya apa?), disimpan dimana, kapan diloadnya, hasil loadnya berupa apa?. Thx b-4, pemula java memang su-lit(susah dan sulit) ya, apa lagi otak ane pentium 2 pas2an. He he, peace ah

JoseScalia said...

Quote "Bang jose cool banget codingnya tapi ane masih bingung ama file database_conn.properties, ne file bentuknya apa(extentionnya apa?), disimpan dimana, kapan diloadnya, hasil loadnya berupa apa?. Thx b-4, pemula java memang su-lit(susah dan sulit) ya, apa lagi otak ane pentium 2 pas2an. He he, peace ah.."

Hmmm file database_conn.properties sebenarnya adalah suatu file properties yang biasa dalam java, silahkan baca link berikut "http://commons.apache.org/configuration/howto_properties.html", File ini cuma file text biasa tapi extensionnya .properties, jika anda menggunakan IDE seperti IntelliJidea, Eclipse atau Netbeans, type file ini masuk dalam extension yang IDE itu kenal. Jika dari artikel diatas file ini akan di load pas pada saat methode public static void main() ketika class ConfigProperties di panggil, hasil loadnya cuma berupa nilai-nilai yang ada dalam file properties tsb untuk kemudian di deklarasikan sebagai sebuah variabel, lihat kode public void init()...

Terima kasih
Semoga Bermanfaat...

Anonymous said...

Well said.

Anonymous said...

bang jose,,tlong infonya dunks,,
gw ud install connector/J buat mysql
di environtment variablenya,tapi ko pas gw running programnya malah keluarin ....ClassNotDefFoundError...seblumnya ga ada masalah klo gw running program sebelum install connector/J'y,,tlung dunk infonya bang jose..or kirimin ke email gw dunk bang jose,ni email nya "or_bgo@yahoo.com".Thanks before"

JoseScalia said...

[qoute]
bang jose,,tlong infonya dunks,,
gw ud install connector/J buat mysql
di environtment variablenya,tapi ko pas gw running programnya malah keluarin ....ClassNotDefFoundError...seblumnya ga ada masalah klo gw running program sebelum install connector/J'y,,tlung dunk infonya bang jose..or kirimin ke email gw dunk bang jose,ni email nya "or_bgo@yahoo.com".Thanks before"
[/quote]

Pastikan instalasi MySqlConnector nya di classpath...kalo saya sendiri jujur tidak pernah menginstall MySQL Connector,
Penggunaan MySQL Connector dalam program biasanya saya lakukan men-setting classpathnya didalam File MANIFEST.MF dalam suatu aplikasi jar file, dan semuanya di lakukan otomatis oleh ant
seperti dalam artikel ini:
http://josescalia.blogspot.com/2008/11/ant-otomatisasi-development-java.html
Cobalah untuk meremove environment variable tsb dan manfaatkan jar file untuk pembuatan aplikasi Java...
Terima kasih telah mengunjungi blog ini

josescalia

Unknown said...

Bagus banget, sudah jalan tapi saya bingung file properties nya sudah saya letakan di folder yang sama dengan class nya tapi tidak terbaca. Tapi kalau saya ketikan full path nya misal : \home\bejo\database_conn.properties bisa terbaca settingan nya.

Salah nya dimana ya suhu

Terima kasih

JoseScalia said...

@hawkeye:
Tidak ada yang salah..hanya anda harus lebih memahami, Runtime dan development time Environment Variable..
Jika anda masukkan fullpath seperti /home/bejo/database_conn.properties, secara default, jika anda menambahkan "/" pada awal string seperti diatas maka Java akan baca dari awal path "SDA" Partisi Hardrive. Namun jika anda tidak menambahkan Fullpath..maka Java akan baca start-path-nya dimulai dari path dimana anda mengeksekusi program tsb..
Coba baca artikel di blog ini yang berjudul "Menambahkan Log4J pada Web Aplikasi Java" disana ada sedikit paparan tentang Full-Path dan Execution Path, mungkin anda bisa lebih memahami Runtime dan Development Time pada aplikasi Java.
Terima Kasih telah mengunjungi Blog ini
Salam
Josescalia

Anonymous said...

Artikel bagus, oya mas itu kenapa yang dipakai untuk class ConfigProperties-nya adalah final class bukan class biasa?

Best Regards

JoseScalia said...

[Artikel bagus, oya mas itu kenapa yang dipakai untuk class ConfigProperties-nya adalah final class bukan class biasa?]

Oh ya..saya memang sengaja membuatnya menjadi final class, biar tidak bisa diturunkan di extends oleh kelas lain. toh dengan class ini sudah cukup untuk membaca property file

Anonymous said...

Saya agak bingung dengan flow programnya, terutama pemakaian variable "instance" dan method getInstance-nya, kalau saya buat seperti ini gimana mas?

public final class ConfigProperties {

//private static String file_properties = null;
private static Properties ppty = null;

private ConfigProperties(){
//private constructor
}

public static void loadProperties(String filename) throws FileNotFoundException, IOException{
if (null==ppty){
try{
System.out.println("LOADING properties...");

ppty = new Properties();
FileInputStream in = new FileInputStream(filename);
ppty.load(in);
in.close();
}
catch(FileNotFoundException e){
throw new FileNotFoundException("File - " + filename + " not found in the working directory");
}
}
}
}
...............................

jadi method getInstance nya saya ganti jadi method loadProperties dan menghilangkan class variable "instance"-nya, kan jadi lebih straight forward gt..gmn mas?

JoseScalia said...

Oh..
Silahkan saja mas, ganti sesuai dengan kebutuhan anda, saya tidak keberatan sama sekali, itulah gunanya berbagi kan...? :P
Terima kasih telah mengunjungi blog ini..

Unknown said...

pas awal run muncul error gini Exception in getProperties=File - config/database_conn.properties not found in the working directory
padahal saya udh buat file database_conn.properties nya
gimmana cara ngatasinya mas,maap yah baru newbie soalnye