SQL Veri tabanın Veri Kaydetmek
İletişim bilgileri gibi
tekrarlayan ve yapılandırılmış verileri veri tabanlarına kaydetmek en ideal
yöntemdir. Bu yazımızda genel olarak SQL veri tabanı sorgularını bildiğinizi
varsayarak anlatımımızı yapacağız. Android üzerinde veri tabanı kullanmak için
ihtiyaç duyduğumuz API android.database.sqlite
paketinde yer alır.
Bir Şema ve Contract Tanımlamak
SQL
veri tabanlarının bir numaralı prensibi (schema) şemalardır. En genel tanımı,
veri tabanını organize etme şeklindedir. Ayrıca sema, veri tabanı oluşturmak
için SQL ifadelerinin yanımsıdır. Belki de Contract diye adlandırılan
self-documentation yapabilen ve şemanızı sistematik olarak açıkça tanımlayan eş
sınıflar oluşturmayı kullanışlı bulabilirsiniz,
Contract
Class (İlişkili Sınıf) URI’ler, Tablolar ve sütunlar için tanımlanan isimleri
barındıran sabitleri içerir. Bu sınıflar sayesinde tanımladığınız bir sabiti
aynı paket içindeki tüm sınıflardan (class) çağırıp kullanabilme kolaylığı
sağlar. Bu şekilde sütunlarınızda yapacağınız en ufak değişiklik tüm
kodlamanıza yansıyacaktır.
Contract
Class ınızı en iyi organize etme şekli, sınıfın kök seviyesinde tüm veri tabanı
tanımlamalarını global yapmaktır. Böylece her tablo için alt sınıflar
oluşturarak bu sütunların kapsanmasını sağlamış olursunuz.
NOT:
BaseColumns ara yüzünü uygulayarak inner sınıfınızın primary
key olan _ID alanını miras almasını sağlarsınız ve bu Android sınıflarından
cursor adaptor gibi sınıfların görmek istediği bir değerdir. Bunu yapmak
zorunda değilsiniz, ancak bu sayede uygulamanızın veri tabanı Android FrameWork
ile uyumlu çalışacaktır.
ÖRNEK:
Tek bir tablo için tablo adı ve sütun adı tanımlayan kod
bloğu
public final class FeedReaderContract { // To prevent someone from accidentally instantiating the contract class, // give it an empty constructor. public FeedReaderContract() {} /* Inner class that defines the table contents */ public static abstract class FeedEntry implements BaseColumns { public static final String TABLE_NAME = "entry"; public static final String COLUMN_NAME_ENTRY_ID = "entryid"; public static final String COLUMN_NAME_TITLE = "title"; public static final String COLUMN_NAME_SUBTITLE = "subtitle"; ... } }
SQL Helper Kullanarak Veri Tabanı Oluşturmak
Veri
tabanınızın nasıl görüneceğini tanımladıktan sonra, veri tabanı ve tabloları
oluşturup koruyacak olan metotları uygulamanız gerekir. Bir tablo oluşturmak ve
silmek için gereken tipik SQL ifadeleri aşağıdaki örnekte gösterilmiştir.
ÖRNEK:
private static final String TEXT_TYPE = " TEXT"; private static final String COMMA_SEP = ","; private static final String SQL_CREATE_ENTRIES = "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" + FeedEntry._ID + " INTEGER PRIMARY KEY," + FeedEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP + FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP + ... // Any other options for the CREATE command " )"; private static final String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;
Android aygıtların dahili
depolama alanlarına kaydederken olduğu gibi, Android Sistem uygulamanız ile
ilişkili private bir veri tabanına kayıt yapar. Verileriniz güvendedir çünkü,
bu varsayılan alan diğer uygulamaların erişimine kapalıdır.
Bu konu
ile alakalı kullanışlı API setleri SQLiteOpenHelper
sınıfında hali hazırda tanımlanmıştır. Veri tabanınıza referans almak için bu
sınıfı kullandığınızda, sistem uygulama başlama anı dışındaki durumlarda sistem
veritabanı oluşturmak ve güncellemek için ihtiyaç duyulduğunda potansiyel uzun
süreli bir çalışma işlemi gerçekleştirir. Bu iki işlem için tüm ihtiyacını olan
şey getWritableDatabase() veya getReadableDatabase()
metotlarıdır.
NOT:
Bu işlemler, AsyncTask veya IntentService gibi uzun soluklu
olacağından getWritableDatabase() veya getReadableDatabase()
metotlarından birini çağırdığınızdan emin olun.
SQLiteOpenHelper kullanmak
için onCreate(), onUpgrade() ve onOpen() metotlarını Override ederek alt sınıflar
oluşturmalısınız. onDowngrade() metodunu da
kullanmak isteyebilirsiniz, ancak buna gerek yoktur.
ÖRNEK:
SQLiteOpenHelper uyglama
örneği
public class FeedReaderDbHelper extends SQLiteOpenHelper { // If you change the database schema, you must increment the database version. public static final int DATABASE_VERSION = 1; public static final String DATABASE_NAME = "FeedReader.db"; public FeedReaderDbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } public void onCreate(SQLiteDatabase db) { db.execSQL(SQL_CREATE_ENTRIES); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // This database is only a cache for online data, so its upgrade policy is // to simply to discard the data and start over db.execSQL(SQL_DELETE_ENTRIES); onCreate(db); } public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { onUpgrade(db, oldVersion, newVersion); } }
SQLiteOpenHelper ın alt sınıflarını hazırlamak için veri
tabanınıza erişirken;
FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
Bir Veri Tabanına Veri Eklemek
ContentValues nesnesini insert()
metoduna geçirerek veri tabanına veri eklemek;
// Gets the data repository in write mode SQLiteDatabase db = mDbHelper.getWritableDatabase(); // Create a new map of values, where column names are the keys ContentValues values = new ContentValues(); values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id); values.put(FeedEntry.COLUMN_NAME_TITLE, title); values.put(FeedEntry.COLUMN_NAME_CONTENT, content); // Insert the new row, returning the primary key value of the new row long newRowId; newRowId = db.insert( FeedEntry.TABLE_NAME, FeedEntry.COLUMN_NAME_NULLABLE, values);
İnsert() metodunun ilk
parametresi basit olarak tablo adıdır. İkinci parametre, ContentValues boş
olduğunda framework tarafından boş bilgisi girilebilen sütun adını içerir. (
bunun yerine bu kısmı siz “null” şeklinde
tanımlarsanız, framework bu kısımda veri
olmadığında herhangi bir sütun eklemesinde bulunmayacaktır.)
Veri Tabanından Bilgi Okumak
Veri
tabanında veri okumak için, query() metodu
kullanılır. Bu metot, veri çekmek istediğiniz sütun ve tercih kriterlerinizi
parametre olarak alır. Bu metot insert() ve update() metotlarını kombine
edebilir. ( getirmek istediğiniz veriyi tanımlayan sütun listesi dışında) . Sorgu
sonuçları Cursor nesnesine döndürülür.
ÖRNEK:
SQLiteDatabase db = mDbHelper.getReadableDatabase(); // Define a projection that specifies which columns from the database // you will actually use after this query. String[] projection = { FeedEntry._ID, FeedEntry.COLUMN_NAME_TITLE, FeedEntry.COLUMN_NAME_UPDATED, ... }; // How you want the results sorted in the resulting Cursor String sortOrder = FeedEntry.COLUMN_NAME_UPDATED + " DESC"; Cursor c = db.query( FeedEntry.TABLE_NAME, // The table to query projection, // The columns to return selection, // The columns for the WHERE clause selectionArgs, // The values for the WHERE clause null, // don't group the rows null, // don't filter by row groups sortOrder // The sort order );
Değerleri okumadan önce her zaman çağırmanız gereken Cursor
hareket metotlarından birini Cursor içindeki bir satıra bakmak için
kullanmalısınız. Genellikle, sorgulama sonuçları içinde ilk veriye konumlanan
pozisyon okuma metodu olan moveToFirst()
metodunu çağırmak, başlangıç için yapmanız gerekendir. Her satır için, Cursor
sınıfının getString() veya getLong() gibi metotlardan herhangi birini
kullanarak bu satırlara ait verileri okuyabilirsiniz. Bu get metotlarından
hangisini kullanırsanız kullanın parametre olarak görüntülemek istediğiniz
sütunun index numarasını kullanmalısınız. Bu bilgiye ise, getColumnIndex() veya getColumnIndexOrThrow()
metotlarıdan birini çağırarak ulaşabilirsiniz.
ÖRNEK:
cursor.moveToFirst();
long itemId = cursor.getLong(
cursor.getColumnIndexOrThrow(FeedEntry._ID)
);
long itemId = cursor.getLong(
cursor.getColumnIndexOrThrow(FeedEntry._ID)
);
Veri Tabanından Bilgi Silmek
Veri tabanınızdaki verilere ait al birimlerde değişiklik
yapmak istediğinizde, update() metodunu
kullanabilirsiniz.
insert() metodunda
kullandığınız söz dizimleri ile (syntax) delete()
metodunda kullandığınız where söz dizimi ile
içerik değerlerini kombine edere bu işlemi gerçekleştirmeniz mümkündür.
ÖRNEK:
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// New value for one column
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
// Which row to update, based on the ID
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
String[] selectionArgs = { String.valueOf(rowId) };
int count = db.update(
FeedReaderDbHelper.FeedEntry.TABLE_NAME,
values,
selection,
selectionArgs);
// New value for one column
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
// Which row to update, based on the ID
String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";
String[] selectionArgs = { String.valueOf(rowId) };
int count = db.update(
FeedReaderDbHelper.FeedEntry.TABLE_NAME,
values,
selection,
selectionArgs);