JDBC Daha Performanslı nasıl kullanırız

CorsaiR

Emektar
27 Ara 2005
1,228
18
Çekirdekten
jdbc ayarları hakkında daha iyi nasıl kullanabiliriz JDBC (Java Database Connectivity) Java nın veritabanına ulaşmak için kullandığı standard API ye verilen addır.JDBC nin etkin kullanımı genel performansı önemli ölçüde etkileyen parametrelerdendir.Aşağıda JDBC hakkında dikkat edilmesi gereken birkaç noktaya değinmeye çalıştım :

1) Veritabanına olan bağlantıyı sağlamak için DataSource kullanmalıdır.
JDBC 2.0+ DataSource u desteklemektedir.DataSource objelerinin konfirigasyonu J2EE container ı üzerinde yapılır, veritabanı bağlantısını sağlar ve yönetir, pool mekanizması ve transaction desteği sağlar.
Eskiden kullanılan yönteme örnek verelim :

Class.forName(“oracle.jdbc.driver.OracleDriver”);
DriverManager.getConnection(“jdbc:eek:racle:thin:mad:host:port:sid”,username,pwd);

Bu DataSource ile birlikte şu şekilde yapılmalıdır :

InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(“java:comp/env/jdbc/OracleDS”)
Connection conn = ds.getConnection();

Not : OracleDS , burada veritabanının adıdır.Uygulama, “ejb-jar.xml” dediğimiz xml dosyasına InitailContext in lookup metodu ile bakar.Karşılığı olan “connection pool” u bulur ve bu pool üzerinden veritabanı bağlantısını kurar.

2) Veritabanı bağlantılarını pool mekanizması üzerinden yapılmalıdır.
Veritabanı’e klasik fiziksel bağlantı kurmak ve bunun üzerinden işlem yapmak maliyetlidir.Connection pool ile kurulan bağlantılar tekrar tekrar kullanılabilir.Ama diğer türlü ,bir bağlantı kurulur ve işlem bitince sonlanır.Pool mantığında ise aynı bağlantı tekrar tekrar kullanılabilir.Pool tanımları application server üzerinde yapılır.

3) Mümkün olduğunca PrepairedStatement kullanılmalıdır.
Veritabanı bağlantısını sağladıktan sonra artık veritabanında işlemler yapmaya başlayabiliriz.Bunu “statement” dediğimiz objelerle sağlarız.3 çeşit statement objesi vardır :

statement
preparedStatement
CallableStatement

“Statement” ve “preparedStatement” ile SELECT,UPDATE gibi temel SQL leri calıştırırken “CallableStatement” ile veritabanı de bir fonksiyon ya da procedure cağırmak için kullanırız.
Statement ile prepairedStatement arasındaki fark , 2.nde bir kere derleme olur ve belirtilen parametreleri girmek suretiyle SQL’in tekrar tekrar kullanılması sağlanır.Bu da performasnı arttırır.1.de ise her çağrılma durumunda derleme işlemleri her seferinde tekrarlanır.Örnekler :
Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery(”SELECT a, b, c FROM Table”);

PreparedStatement pstmt = con.prepareStatement(
“INSERT INTO EMPLOYEES (NAME, PHONE) VALUES (?, ?)”);
pstmt.setString(1, theName);
pstmt.setString(2, thePhone);
pstmt.executeUpdate();

4) Kullandıgımız herhangibir kaynağı işimiz bitince kapatmalıyız.
Kullandıgımız kaynak connection olsun, ResultSet olsun, statement lardan biri olsun işimiz bitince kapatılmalıdır.Bunu try-catch bloğundan sonraki finally bloğu ile sağlayabiliriz.
ResultSet rset = null;
PreparedStatement pstmt = null;
Connection conn = null;

try {

}
catch(Exception e) {

}
finally{
if(rset!=null)
rset.close();

if(pstmt!=null)
pstmt.close();

if(conn!=null)
conn.close();
}

5) AutoCommit özelliğini control altında tutmalıdır.
JDBC ile sağlanan veritabanı bağlantıları varsayılan olarak “autocommit”tir.Yani yapılan her DML işlemi sizin isteğiniz dışında commit lenir.Bu hem istenmeyen durumlara yol açar hem de çok sık commit etmenin oluşturacğı olası performans kayıplarına yol açabilir:

pstmt.setLong(1,2345);
pstmt.setString(2,”Sam”);
pstmt.execute(); à COMMIT
pstmt.setLong(1,2346);
pstmt.setString(2,”Steve”);
pstmt.execute();à COMMIT
pstmt.setLong(1,2347);
pstmt.setString(3,”Scott”);
pstmt.execute();à COMMIT

Bunu engellemek oldukça kolaydır.Yapılması gereken tek şey DML işlemlerimiz başlamadan autocommit özelliğini kapamak ve işlem bitince kendimizin commit etmesidir.Yani :

connection.setAutoCommit(false);
pstmt.setLong(1,2345);
pstmt.setString(2,”Sam”);
pstmt.execute();
pstmt.setLong(1,2346);
pstmt.setString(2,”Steve”);
pstmt.execute();
pstmt.setLong(1,2347);
pstmt.setString(3,”Scott”);
pstmt.execute();
connection.commit();

6) Tekrarlanan Batch işlemler için statement batching kullanılmaldır.
Diyelimki devamlı sekilde bir insert yapıyoruz, bunu da preparedStatement ile yaptık.Her seferinde derlem olmuyor aynı SQL tekrar tekrar kullanılabiliyor.Bu uygulamamızı daha da performanslı yapmanın yolu var.Diyelim 10 tane insert yapılacak.Bunu 10 kez veritabanına gidip yapmak mıdır yoksa 10unu birden tek seferde gidip yapmak mıdır? Elbette 2.si.JDBC bu konuda da esneklik sağlıyor.Aşağıdaki gibi bir değişiklikle bu tip işlemlerimizin batch seklinde yapılmasını sağlayabiliriz :

PreparedStatement pstmt = null;
pstmt = conn.prepareStatement(”insert into emp(empno,ename) values(?,?)”);
pstmt.setLong(1,101);
pstmt.setString(2,Ahmet);
pstmt.addBatch();
pstmt.setLong(1,102);
pstmt.setString(2,Alperen);
pstmt.addBatch();

int resultValues[] = pstmt.executeBatch();
// examine resultValues[] to see status of
// each batch operation

7) ResultSet i gereğinden fazla şişirmemelidir.
Örnegin 30 kolonlu bir tabloda bir işlemimiz için sadece 4 kolona ihtiyacımız var iken “select *” kullanmak gereksiz kaynak tüketmeye ve performans kaybına yol açacaktır.
“select *” haliyle calistirildığı anda network üzerinde giden gelen veri büyüklüğü ile 4 kolounu veri büyüklüğünü karşılaştırmak konuyu daha iyi anlamamızı sağlayacaktır.

Bunların yanında aşağıdaki noktalara da dikkat etmekte fayda var :

Kolon ve satir bazında cekilen data miktarını azaltmak ya da arttırmak performansı etkiler.Bunu kontrol etmek için Statement objesinin setMaxRows, setMaxFieldSize, and SetFetchSize metodlarından faydalanılır.

ResultSet ile değer alırken getObject metoduyerine alacağımız verini tipinde bir get metodu kullanmak daha performanslı olacaktır.(getInt(), getString() gibi)

Yine ResutSet ile kolon bilgilerini alırken kolonların adını kullanmak yerine select teki sırasına göre kullanmalıdır.(rs.getString(1) gibi)
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.