Android Programlama Ders 41: SQLite’ta Kullanılan İşlemleri İnceliyoruz

In Makale, Mobil, Pratik by Victor CuiumjuLeave a Comment

Android Programlama Ders 41′de veri tabanı kullanarak SQLite’ta kullanılan temel işlemleri inceleceğiz.

Veri tabanın işleminin (Transaction) ne olduğunu hakkında konuşalım. İşlemin amacı veriyle çalıştığımız zaman “ya tüm ya hiç” prensipleri taşıyor. Mesela veri tabanına bir veri paketi kaydetmek gerekiyor. Veri ya tüm kaydedilecek ya da hiç kaydedilmeyecek. Eğer verilerin yarısı kaydedilmişse, kaydedilen verilerin iptal edilmesi söz konusu olacaktır. Bu imkanı bize SQLite transaction (işlem) sunuyor.

Konuyu daha iyi anlamak için basit bir uygulamayı oluşturalım.

Projeyi oluşturalım:

  • Project name: P0041_SQLiteTransaction
  • Build Target: Android 4.2
  • Application name: SQLiteTransaction
  • Package name: tr.example.sqlitetransaction
  • Create Activity: MainActivity

Bu proje için ekranı kullanmayacağız. Bu yüzden direkt MainActivity.java’yı oluşturuyoruz.

MainActivity.java:

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {

  final String LOG_TAG = "myLogs";

  DBHelper dbh;
  SQLiteDatabase db;

  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.d(LOG_TAG, "--- onCreate Activity ---");
    dbh = new DBHelper(this);
    myActions();
  }

  void myActions() {
        try {
          db = dbh.getWritableDatabase();
          delete(db, "mytable");

          db.beginTransaction();
          insert(db, "mytable", "val1");

          Log.d(LOG_TAG, "create DBHelper");
          DBHelper dbh2 = new DBHelper(this);
          Log.d(LOG_TAG, "get db");
          SQLiteDatabase db2 = dbh2.getWritableDatabase();
          read(db2, "mytable");
          dbh2.close();

          db.setTransactionSuccessful();
          db.endTransaction();

          read(db, "mytable");
          dbh.close();

        } catch (Exception ex) {
          Log.d(LOG_TAG, ex.getClass() + " error: " + ex.getMessage());
        }
      }


  void insert(SQLiteDatabase db, String table, String value) {
    Log.d(LOG_TAG, "Insert in table " + table + " value = " + value);
    ContentValues cv = new ContentValues();
    cv.put("val", value);
    db.insert(table, null, cv);
  }

  void read(SQLiteDatabase db, String table) {
    Log.d(LOG_TAG, "Read table " + table);
    Cursor c = db.query(table, null, null, null, null, null, null);
    if (c != null) {
      Log.d(LOG_TAG, "Records count = " + c.getCount());
      if (c.moveToFirst()) {
        do {
          Log.d(LOG_TAG, c.getString(c.getColumnIndex("val")));
        } while (c.moveToNext());
      }
      c.close();
    }
  }

  void delete(SQLiteDatabase db, String table) {
    Log.d(LOG_TAG, "Delete all from table " + table);
    db.delete(table, null, null);
  }

  class DBHelper extends SQLiteOpenHelper {

    public DBHelper(Context context) {
      super(context, "myDB", null, 1);
    }

    public void onCreate(SQLiteDatabase db) {
      Log.d(LOG_TAG, "--- onCreate database ---");

      db.execSQL("create table mytable ("
          + "id integer primary key autoincrement," 
          + "val text"
          + ");");
    }

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
  }

}

Kodu inceleğelim. myAction metodunda insert (Yapıştır), read (Oku) ve delete (Sil) işlemleri birleştirdim. Metodunda veri tabanına bağlıyoruz, tabloda (mytable) verileri siliniyoruz ve val1 satırı yapıştırıyoruz. Sonraki aşamada bildirime tablodan kayıtları yazdırıyoruz ve bağlantıyı kapatıyoruz.

Kaydedelim ve çalıştıralım.

Bildirime bakalım:

— onCreate Activity —
— onCreate database —
Delete all from table mytable
Insert in table mytable value = val1
Read table mytable
Records count = 1
val1

Herşey doğru kaydını başarıyla yapıştırdık ve bildirime yazdırdık. Şimdi işlem (Transaction) kullanmayı deneyelim. myAction metodu değiştirelim:

void myActions() {
     db = dbh.getWritableDatabase();
     delete(db, "mytable");
     db.beginTransaction();
     insert(db, "mytable", "val1");
     db.endTransaction();
     insert(db, "mytable", "val2");
     read(db, "mytable");
     dbh.close();
 }

Veri tabanına bağlanıyoruz, tabloyu temizliyoruz, beginTransaction metodu kullanarak işlemi (Transaction) başlatıyoruz, val1 yapıştırıyoruz ve endTransaction yardımıyla işlemi kapatıyoruz. Sonraki aşamada val2 kaydını yapıştırıyoruz, bildirime yazdırıyoruz ve bağlantıyı kapatıyoruz. Kaydedelim ve çalıştıralım. Bildirime bakalım:

— onCreate Activity —
Delete all from table mytable
Insert in table mytable value = val1
Insert in table mytable value = val2
Read table mytable
Records count = 1
val2

Bildirimden görüyoruz ki tabloda sadece ikinci kayıt mevcut. Bunun sebebi, işlemin başarıyla kapatılması (setTransactionSuccessful) metodunu kullanmadık. myAction metodu değiştirelim:

void myActions() {
     db = dbh.getWritableDatabase();
     delete(db, "mytable");
     db.beginTransaction();
     insert(db, "mytable", "val1");
     db.setTransactionSuccessful();
     insert(db, "mytable", "val2");
     db.endTransaction();
     insert(db, "mytable", "val3");
     read(db, "mytable");
     dbh.close();
   }

Aynı şekilde veri tabanına bağlanıyoruz, tabloyu temizliyoruz ve val1 yapıştırıyoruz setTransactionSuccessful metoduyla işlemin başarılı olduğunu belirliyoruz, val2 kaydı yapıştırıyoruz, işlemi kapatıyoruz, val3 kayıdı yapıştırıyoruz ve read metodu kullanarak bildirime içindekileri yazdırıyoruz. Bağlantıyı kapatıyoruz (dbh.close()). Kaydedelim ve bildirime bakalım:

— onCreate Activity —
Delete all from table mytable
Insert in table mytable value = val1
Insert in table mytable value = val2
Insert in table mytable value = val3
Read table mytable
Records count = 3
val1
val2
val3

Tüm kayıtları başarıyla yapıştırdık. Dikkat ederseniz val2 setTransactionSuccessful metodundan sonra yapıştırdık. Tavsiye edilen yöntem kayıtları setTransaction Succesful metodundan önce yapıştırmak.

İşlem (Transaction) başladığında veri tabanı bağlantısını bloke ediyor. Örnekte işlemi gerçekleşince veri tabanına yeni bağlantı kurmayı deneyelim. myAction metodu değiştirelim:

void myActions() {
     try {
       db = dbh.getWritableDatabase();
       delete(db, "mytable");
 
       db.beginTransaction();
       insert(db, "mytable", "val1");
 
       Log.d(LOG_TAG, "create DBHelper");
       DBHelper dbh2 = new DBHelper(this);
       Log.d(LOG_TAG, "get db");
       SQLiteDatabase db2 = dbh2.getWritableDatabase();
       read(db2, "mytable");
       dbh2.close();
 
       db.setTransactionSuccessful();
       db.endTransaction();
 
       read(db, "mytable");
       dbh.close();
 
     } catch (Exception ex) {
       Log.d(LOG_TAG, ex.getClass() + " error: " + ex.getMessage());
     }
  }

Veri tabanına bağlanıyoruz, tabloyu temizliyoruz, işlemi başlatıyoruz, kayıdı yapıştırıyoruz. Sonraki aşamada yeni bağlantıyı oluşturuyoruz. İkinci bağlantıyı (db2) kullanarak mytable tablosundakileri okuyoruz. İkinci bağlantıyı kapatıyoruz, işlemi kapatıyoruz, birinci bağlantıyla mytable tablosundan içindekileri okuyoruz ve birinci bağlantıyı kapatıyoruz. Kaydedelim ve çalıştıralım.

Bildirime bakalım:

— onCreate Activity —
Delete all from table mytable
Insert in table mytable value = val1
create DBHelper
get db
class android.database.sqlite.SQLiteException error: database is locked

Bildirimde veri tabanına ikinci defa bağlantısında hata oluştuğunu görebiliriz. Eğer koddan işlemi yönetilen satırı siler ve yeniden programı çalıştırırsanız, bildirim hatayı göstermeyecek.

İşlemi kullanmak tavsiye edilen formu aşağıdaki veriyorum:

db.beginTransaction();
     try {
       ...
       db.setTransactionSuccessful();
     } finally {
       db.endTransaction();
     }

Ders Sonu Notları:

Bugünkü derslerimizde işlem (Transaction) konusuna değindik. Gelecek derste veri tabanının versiyon yapısını değiştirmeyi öğreneceğiz.