Android

Android SQLite Database Kullanımı

Merhabalar arkadaşlar,

Bugün SQLite’ın ne olduğuna ve  android üzerinde  nasıl kullanıldığına değineceğim. Bilindiği üzere çoğu uygulamada verilerin bir yerlerde depolanması gerekiyor. Bunun için en iyi seçimlerden birinin veritabanı olduğu şüphesis. Sözü fazla uzatmadan konuya girelim artık. Faydalı olması dileğiyle.

SQLite Nedir ?

Kullanımı basit, çok yer kaplamayan ve mobil cihazlarda rahatlıkta kullanılabilen açık kaynak kodlu ve sistem bağımsız bir veritabanı kütüphanesi ve motorudur. SQLite, onlarca programlama dili ile kullanılabilir. Az yer kaplaması ve istenilen hızda veri işlemleri yapabilmesi tercih sebepleri arasındadır.

SQLite Veritabanında Desteklenen Veri Tipleri

  • TEXT
  • NUMERIC
  • INTEGER
  • REAL
  • NONE

SQLite Veritabanının Android Üzerinde Kullanımı

Bilindiği üzere Android üzerinde otomatik olarak hazır bir veri tabanı sunulmamaktadır. Eğer android uygulamamız için bir veritabanı oluşturmak istiyorsak, kendi tablolarımızı ve veri tiplerimizi belirlemeli  daha sonrada bunlar arasındaki ilişkileri düzenlemeliyiz. Yani sıfırdan bir veritabanını hayata geçirmeliyiz diyebiliriz. Bu ilk bakışta biraz karmaşık gelebilir, hatta sqlite’ın görsel arayüzünün olmadığını düşünürsek dahada karmaşıklaştığını düşünebiliriz; fakat daha önce sql ile biraz ilgilenmiş iseniz çok rahatlıkta sqlite’a uyum sağlayabilirsiniz. Ayrıca üçüncü parti araçlarla görsel arayüz desteği sağlanabilmektedir.

Şimdi android üzerinde bir veritabanının nasıl oluşturulduğuna ve temel operasyonların (SELECT,DELETE,INSERT,UPDATE) nasıl kullanıldığına bir göz atalım.

Öncelikle şunu söylemeliym ki, SQLite veritabanı oluştururken bazı hazır sınıfların altsınıfları olarak türetilen sınıflar üzerinde işlem yapmak bizlere her zaman fayda sağlayacaktır. Kütüphane tarafından sağlanan sınıflar hem mantıksal bir bütünlük hemde veritabanını yönetmeyi kolaylaştıracak yetenekleri desteklemektedir. Bir veritabanının nasıl oluşturulduğunu ve operasyonların nasıl çalıştırıldığını aşağıdaki adımlarda bulabilirsiniz.

1. SQLiteOpenHelper’dan türetilen bir sınıf oluşturmak.

public class TestDBHelper extends SQLiteOpenHelper { }

Bu bizlere  2 methodu kullanma zorunluluğu getirecektir.

  1.  onCreate(SQLiteDatabase db) : Veritabanı ilk oluşturulduğunda çağrılır. Tabloları, viewleri, trigger vb. yapılar bu method içinde oluşturulur.
  2.  onUpgrade(SQLiteDatabase db, int eskiVersiyon, int yeniVersiyon) : Veritabanı üzerinde herhangi bir değişiklik olduğunda çağrılır. Tablo değişimi vb. gibi.

2. Sabitleri tanımlamak

public class DenemeDBHelper extends SQLiteOpenHelper {

static final String dbAdi="DBTEST";
static final String KISITABLE ="KISI";
static final String _ID="_ID";
static final String ad ="ad";
static final String soyad ="soyad";
static final String yas ="yas";
static final int version =1;

//constructer()...
//onCreate()....
//onUpgrade()....
}

Sabitleri helper sınıf içinde tanımladığımız gibi farklı bir sınıf içerisinde de tanımlayabiliriz. Yeterki erişilebilir ve kullanımı anlaşılabilir olsun. Ben örnek için kişinin ad,soyad ve yaşının tutulduğu tabloyu içinde barındıran bir veritabanını baz aldım. (Static ve final olarak tanımladığımıza dikkat ediniz !)

3. Constructer

public TestDbHelper(Context context){

super(context,dbAdi,null,version);
}

4. onCreate() ve Tablo Oluşturmak

Tablo oluşturma işlemlerimizi onCreate() methodu içerisinde yapıyoruz.  Aşağıda bir kişi tablosu oluşturmak için gereken sql cümleciğini ve bir tablonun nasıl oluşturulduğunu bulabilirsiniz.

public void onCreate(SQLiteDatabase db) {

db.execSQL ("CREATE TABLE"+ KISITABLE+"("+_ID+" INTEGER PRIMARY KEY AUTOINCREMENT,"+ ad+"        TEXT, "+soyad+" TEXT, "+yas+" INTEGER);");

}

5. onUpgrade()

Veritabanında herhangi bir modifikasyon olduğunda onUpgrade() methodu çalıştırılır. Daha sonrasında çağrılan onCreate() methodu değişikleri hayata geçirmeye yarar.  (Drop Table , Alter Table, Drop arg. Alter arg)

public void onUpgrade(SQLiteDatabase db, int eskiVersiyon, int yeniVersiyon){

db.execSQL("DROP TABLE IF EXISTS"+KISITABLE);

onCreate(db);

}

6. Veritabanı İşlemleri için Gereksinimler

  • close() : Veritabanını kapatır.
  • getReadableDatabase() : Okunabilir bir veritabanı sunar. Select işlemleri için uygundur.
  • getWritableDatabase() : Yazılabilir bir veritabanı sunar update,delete ve insert işlemleri için uygundur.

7. Queryleri Çalıştırmak

Sqlite hem bilinen sql cümleciklerini (rawQuery()) desteklemektedir hem de kendi içinde özelleşmiş sorgulama methodları bulunmaktadır.

  • db.rawQuery(String sql, String[] selectionArgs) : Örneğin SELECT * FROM KISITABLE sql cümleciğini kullandığımızda tablodaki tüm verileri tamamıyle elde edebiliriz. Döndürülen sonuç Cursor tipindeki değişkene atanır .
SQlite’ın özelleşmiş methodları ;
  • query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
  • insert(String table, String nullColumnHack, ContentValues icerikDegerleri)
  • delete(String table, String whereCumlecigi, String[] whereArgumanları)
  • update(String table, ContentValues icerikDegerleri, String whereCumlecigi, String[] whereArgumanlari)
Yukarıdaki methodların kullanımını kısaca örneklemek gerekirse;

public Cursor rawQueryTest() {

Cursor sonuc= new Cursor();

sonuc=db.rawQuery("SELECT_ID,ad,soyad,yas FROM KISI, null);
}

public Cursor queryTest(){

String[] columns={_ID, ad};
String[] isimDegeri={"Tugrul"};
Cursor sonuc=db.query (KISITABLE, columns, "ad=?", isimDegeri, null, null, null);

return sonuc;

}

private void insertTest(String a, String s, int y) {

ContentValues cv=new ContentValues(3);

cv.put(ad,a);
cv.put(soyad,s);
cv.put(yas,y);

db.insert(KISITABLE, null, cv);

}

private void deleteTest(int id) {

String[] args={String.valueOf (id)};
db.delete (KISITABLE, "_ID=?", args);

}

8. Cursor Kullanımı

Cursor c = new Cursor();

  • startManagingCursor(c) : Cursor üzerinde işlemler yapabilmeyi sağlar.
  • getCount() : Veritabanındaki kayıt sayısını döndürür.
  • moveToFirst() : Cursor veri tabanındaki ilk kayda gider
  • moveToNext() : Cursor bulunduğu konumdan bir sonraki kayda geçer.
  • isAfterLast() : Son satırdan bir önceki mi sorgulaması yapar
Bunların dışında  getColumnNames(), getColumnIndex(), getString(), getInt() methodları veritabanı işlemleri sırasında sıklıkla kullanılmaktadır.
 Tüm verilerin nasıl getirildiğini ve verilere nasıl ulaşıldığını gösteren kod parçasını aşağıda bulabilirsiniz.

public void cursorTest() {

Cursor c = db.rawQueryTest();
startManagingCursor(c);
if (c.moveToFirst()) {
do {

int id1 = c.getInt(c.getColumnIndex(_ID));
String ad1 = c.getString(c.getColumnIndex(ad));
String soyad1= c.getString(c.getColumnIndex(soyad));
String yas1 = c.getInt(c.getColumnIndex(yas));

//alınan verilerden nesne oluştur dizi vektor, list vb. ekle

} while (c.moveToNext());
}
}

Yazımda sqlite veritabanının android üzerinde nasıl kullanıldığına temel operasyonları örnek alarak kısa bir giriş yapmak istedim. Uygulamalarınızda yardımcı olması dileğiyle . iyi çalışmalar diliyorum.
Okuduğunuz için teşekkürler 😉
.
.
.
Kaynakça :
developer.android.com, wikipedia, arsivyazilim.com, sqlite.org, The Android Developer’s CookBook (James Steele, Nelson To)




22 Comments

  1. Tebrikle çok açıklayıcı ve faydalı bir yazı olmuş, android içerikli ve anlaşılır. Türkçe kaynak bulmak oldukça zor teşekkür ederiz.

    Ayrıca bir de soru sormak isterim, android sqlite veritabanlarını kendi içerisinde tutuyor ve genelde de bu yeterli oluyor sanırım peki ağ üzerinde farklı bir yerde bulunan bir sqlite veritabanından androidle nasıl haberleşebiliriz ?

    1. Rica ederim, elimden geldiğince android konusunda paylaşımlarda bulunmaya çalışıyorum bloğumda. Soruna gelince, daha önce hiç uzak bir veritabanına android ile erişim yapmadım; ama uzak veritabanından verileri web servisi olarak sunabildiğinde çok rahat kullanabilirsin. Sorguyu gönderip cevabı alabileceğin bir web servisi mesela.
      Bu arada sqlite’ın yeterli olmaması için sağlam ve veri yükü getiren bir uygulama olması gerekiyor. Kurumsal uygulamalar için söylediğin düşünülebilir belki. Ama gündelik hayattaki uygulamalar için sqlite’ın yeteceği kanaatindeyim. Saygılarımla, iyi çalışmalar.

  2. Hızlı cevap için teşekkürler,

    Aslında düşündüğüm projede aynı ağ üzerindeki birden fazla android cihazı sqliet yada mssql vertabanı ile haberleştirmek istiyorum bu yüzden web servis yerine ağdan bağlantı kurabileceğimi düşünmüştüm, fakat gözlemlediğim ve senin de söylediğin gibi genel olarak android geliştiriciler farklı cihazları web servis ile haberleştirmeyi tercih ediyorlar.
    Tekrar teşekkürler.

    1. Ben teşekkür ederim . Ağ üzerinden de bağlantı kurabilmem mümkün tabikide. Şu anda o konu üzerinde yeterli deneyim ve bilgiye sahip değilim bundan dolayı alternatifler sunmanın faydalı olabileceğini düşünmüştüm. İyi çalışmalar diliyorum.

  3. Paylaşımınız için çok teşekkürler. Çok yardımcı ve anlaşılır.
    Bir sorum olacaktı sqlite veritabanında tablo ilişkilendirme ve bu ilişkilendirme sonrası delete update ve insert fonksiyonları nasıl çalışıyor yardımcı olursanız çok sevinirim.

    1. Öncelikle çok teşekkürler. Normal bir db tablosu ilişkileri oluştururken nasılki “foreing key” ve “cascade” gibi ilişki ifadeleri kullanıyoruz. SQLite’ta da aynı şekilde aslında. Şimdi örnek yazmak isterim ama biraz yoğunum bugünlerde, cevabıda kısa bir boşluğumda veriyorum. Android multiple table sample diye bir arama yapabilirsin, yardımcı olacaktır. Bir sıkıntın olursa da kısa bir süre içinde geri dönüş yapmaya çalışırım. iyi çalışmalar…

  4. Merhabalar;
    Öncelikle bu güzel makale için teşekkür ederim.

    SQLite karşılaştığım bir problem var. Ona çözüm arıyorum yardımcı olabilirseniz sevinirim.

    Tablolarda büyük türkçe harflerle kayıtları tutuyorum. Türkçe karakterlerle arama da yapabiliyorum. Fakat şunu yapmak istiyorum.

    Örnek: “KUCUK” aradığımda da “KÜÇÜK” gelsin, bunu nasil çözebilirim.

    teşekkür ederim.

    1. Merhaba,

      İki şekilde yapabilirsin;

      1- Türkçede benzer karakterler için bir dönüştürme yapabilirsin. U için aynı zamanda ü lü halinide “veya” olarak arayabilirsin.

      2- Benzerlik oranından sorgulayabilirsin. O zaman benzerlik olarak belirlediğin kriterlere uyanlar getirilir. küçük yerine Küüçk yazdığında da küçük key değerindekileri getirebilirsin. veya benzerliği biraz düşürürsen kucuk küçük aramasıda yapabilirsin.
      * Ya da Önce Türkçe karakter dönüşümü yapar dönüşümle elde ettiğin stringleri benzerliğe göre arayabilirsin. Bu daha mantıklı olcaktır.

      İyi çalışmalar.

  5. Merhaba Tugrul bey,bilgisayar mühendisliği öğrencisiyim ve bitirme projemi android üzerinde yapıyorum projem bitti fakat kurduğum database emulatörde çalışırken apk dosyasını telefona atıp yüklediğimde database’i görmüyor..sanırım database path’inde bir sıkıntı var bunu nasıl çözebilirim.Yardımcı olursanız sevinirim.
    İyi çalışmalar diliyorum…

    1. Merhabalar,

      External olarak db oluşturuyor daha sonra ilgili path’e byte byte koplayalarak mı kullanıyorsunuz, yoksa direk örnekte belirttiğim gibi kod içerisinden mi ?

      Eğer ilkini tercih etmişseniz path hataları ve anlamsız bazı hataları almanız mümkün. Diğer yöntemi izliyor iseniz, path vermek yerine örnekte belirttiği gibi kullanın. Zaman zaman kendi cihazımda çalışıp başka cihazlarda çalışmayan db kullandığım projeler oldu. Hala anlam veremediğim nedenlerden sıkıntı çıkabiliyor.

      Tşk, iyi çalışmalar.

      1. Merhabalar paylaşım için teşekkürler. Benim bir türlü çözemediğim ve araştırmalarım sonucunda da çözüm bulamadığım bir problemim var. Sqlite veri tabanı oluşturduktan sonra veri ekliyorum, uygulamayı telefona atınca bu verilerin olmadığını veritabanının boş geldiğini görüyorum. bu sorunu nasıl çözebilirim yol gösterebilecek birisi yok mudur?

        1. Selamlar,

          Dataları emülatörde oluşturuyorsun, uygulama yüklendiğinde beraberinde değil. Anladığım kadarıyla yapmak istediğin o verileri emülatörde yükleyeyim sonra uygulamayı attığım telefonlarda da olsunlar. Bu mobil development ile ilgilenen kişilerin yaptığı küçük hatalardandır. Sen telefona uygulamayı load etmek istediğinde, eclipse vb. IDE üzerinde bulunan kod load edilecektir, emülatördeki uygulama değil !

          Diğer yandan emülatörlerde bir çeşit cihaz gibidir ve eklediğin veriler sadece emülatörün lokalinde kalacaktır ve uygulamanın load klasörleriyle zaten bir alakası olmayacaktır.

          Bundan dolayı eklediğin verilerin uygulamayı telefona attığında bulunmaması normal.

          Çözüme gelince; Assets kısmına çeşitli dosya türlerinde veriyi ekleyebilir, daha sonra ordan alıp kullanabilirsin. Uygulama paketiyle birlikte load edilebilecek bir lokasyonda olmalı veriler.
          Tavsiyem çok büyük veya karışık veriler yoksa elinde, assets içerisinde txt dosyasında dahi saklayabilirsin. Verilerin büyük ve sürekli sql sorguları çalıştırmanı gereken durumlar var ise eğer, direk assets dosyasına .sql uzantılı dosyalar oluşturabilir ve uygulama ilk açıldığında istediğin bir lokasyona o dosyaları taşıyabilirsin. Her şey senin elinde.

          Assetmanager ve external db in android vb. şeklinde arayabilirsin.

          İyi çalışmalar, kolay gelsin.

  6. Benim merak ettiğim MainActivity.java dosyasında nasıl göstereceğim?

    DenemeDbHelper ddb=new DenemeDbHelper ();
    ddb.onUpgrade(…….) falan mı?

  7. Merhaba, Ben bu veritabanındaki verileri bir obje ile özdeşleştirmek istiyorum. örnek olması açısından bir harita yüklediğimi var sayalım sadece yolların olduğu yolların şerit sayılarının tutulduğu bi veritabanı oluşturup yollarla bunları bağlamak istiyorum nasıl yapabilirim?

    1. Verileri bir obje ile tabiki özleştirebilirsin. Zaten de öyle. Hatta bunu yaparken bazı ORM araşları var android için,, onları kullanabilirsin. Cadde, sokak vb. veritabanı oluşturmak istiyorsan bunu neden mobil cihazda yapasın ki. Bir web uygulamasıyla mobil uygulamana servis edebilirsin. Ayrıca yandex haritalar, googlemaps haritayla ilgili bulabileceğin hemen hemen bütün verileri sağlar durumda. Mecburiyetin yoksa tekerleği yeniden icaet etmeni tavsiye etmem;) İyi çalışmalar.

  8. Merhabalar ,

    Android için yarattığım sqlite veritabanında bir text alanı yarattım. Türkçe karekterlerinde olduğu metinler giriyorum. Fakat bunu uygulamamda göstermek istediğimde türkçe karekterler bozulmakta. Nasıl bir çözüm önerirsiniz

    1. Ozan Selam,

      Kullanılan cihazın dili önemli, zaman zaman sorun çıkabiliyor bu noktada. Db’ye insert etmeden önce String karakteri UTF-8 charset yaptığında da çözülüyor genelde.

      Debug esnasında db’den ne cevap döndüğüne bakabilirsin. Arayüze geçirmeye çalıştığında da problem yaşıyor olabilirsin.

      Şu ana kadar karşılaştığım problemleri bu şekilde gidermeyi başardım.

      Ayrıca aşağıdaki bağlantı da yardımcı olur umarım.
      http://stackoverflow.com/questions/4276215/make-sure-the-sqlite-on-android-uses-utf-8-as-a-charset

      İyi çalışmalar.

  9. Paylaşımınız için teşekkürler. Android’e yeni başlamış biri olarak paylaşımınızı oldukça faydalı ve kolay anlaşılır buldum.
    Benim yapmam gereken bir uygulama var ve bu uygulamada kullanıcı bir veri girecek ve girilen verinin veritabanındaki karşılığı textview’de görünecek. Tıpkı sözlük uygulaması gibi. Araştırdığım kadarıyla veritabanından bahsedilen hemen hemen her sitede veritabanındaki tüm verileri çekmeyi anlatmışlar ya da eklenen veriyi göstermişler. Ben ise örneğin veritanında adını girdiğim kitabın yazarının adını textview’de göstermek istiyorum. Bunu nasıl yaparım ? Yardımcı olabilirseniz çok sevinirim.
    İyi çalışmalar.

    1. Murat Selam,

      Geri bildirimin için teşekkürler.

      Öncelikle sqlite ile ilgili uygulama içeriğine sahip yazımı incelemeni tavsiye ederim.(http://tugrulasik.com/2011/12/21/android-not-defteri-uygulamasi/ )

      Diğer yandan yapman gereken sadece SQL hazırlamak, örneklemek gerekirse;

      Tablo adın kitap ve bazı alanların isbn,yazar_adi,kitap_adi,baski_tarihi vb. olsun.

      select yazar_adi from kitap where kitap_adi like ‘%(yazar_adi_buraya)%’ olarak çektiğinde sana dışarıdan girmiş olduğun yazar adina ve benzerlerine ait kitaplari getirecektir.

      Direk sorgu yapmak istediğinde ise;
      select yazar_adi from kitap where kitap_adi=’yazar_adi_buraya’

      cümleciğini kullanabilirsin.

      Not defteri uygulamasını detaylı bir şekilde inceledikten ve kısa bir araştırma yaptıktan sonra çok rahat yapabilirsin.

      İyi çalışmalar.

  10. Merhaba
    Hızlı geri dönüşünüz için teşekkürler. Not defteri uygulamanızı incelemeye devam ediyorum. SQL ile select kullanmak hiç aklıma gelmemişti. Çok teşekkür ederim. Ama şimdi de şöyle bir sorum olacak. SELECT yazar_adi FROM kitaplik WHERE kitap_adi=’don kişot’ şeklinde kodladığımda “cervantes” yanıtını alıyorum. Ancak kullanıcı “don kişot” yerine başka bir kitap adı girerse çalışmayacaktır. Kullanıcının girdiği kitap adını bu SQL koduna nasıl aktarabilirim? Bunda da %s gibi bir kullanım var mıdır?
    Şimdiden teşekkürler. Saygılar.

    1. Ordaki sql’i zaten kullanıcının girdiği text ile cekeceksin ;). where=’????kullanicinin textviewdengirdiği’

Comments are closed.