Android Room Kütüphanesi Kullanımı

2020 yılında ilk makalemle sizlerleyim, yaklaşık neredeyse 1 yıldır blog makalesi paylaşmıyordum. İnşallah bu yıl daha verimli yazıları ele alırım diyelim.

Sizlere bu makalemde Room kütüphanesi nedir ?, Android’de Room Kütüphanesinin yeri ve sağladığı kolaylıklar gibi konularda bilgilerimi paylaşmaya çalışacağım, yararlı olmasını diliyorum 🙂

Room Kütüphanesi nedir ?

Android’in AndroidX (Android Jetpack) ile birlikte getirdiği Persistence Library’lerden biridir. Yani Android Architecture’e eklenmiş yeni bir yapıdır. SQLite’ı daha performanslı ve efektif kullanılmasına olanak tanıyan, bir nevi hayat kurtarıcı kütüphane olarak sayabiliriz. Geleneksek yöntem ile Android’de bir CRUD işlemi yapabilmek için SQLiteDatabase veya SQLiteOpenHelper gibi sınıfları kullanmak gerekiyordu. Verileri ekleyebilmek için ekle, sil, güncelle gibi metotları tek tek yazıyorduk yada Harici SQLite veritabanını assets klasöründen okuyarak işlemler gerçekleştiriyorduk(Yeri gelir yine kullanırsınız o ayrı).

Şimdi lafı, saçmalığı bir kenara bırakıp heyecanla bu kütüphanenin nasıl kullanıldığını, anlatmaya başlamak istiyorumm.

Projemin Gradle Scripts altında bulunan build.gradle(Module: app) dosyasını açıp, depentencies scope’u içerisine;
implementation ‘android.arch.persistence.room:runtime:1.1.1’

ekliyorum. Diğer build.gradle dosyamızda repositories scope’larında ise, google() ekli olması gerekiyor, zaten varsayılan olarak geliyor, yoksa ekleyiniz.

Bu yapacağımız çalışmada ben Telefon Rehberi ile alakalı olarak bir örnek hazırlamak istedim.

MainActivity.java dosyamızın xml arayüz tasarımını (activity_main.xml) hazırlayalım;

4 Adet TextView (etAd,etSoyad,etGsm ve etNot), 2 Adet Buton (btnKisiEkle,btnKisiler) ekleyelim.
<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”
xmlns:app=”http://schemas.android.com/apk/res-auto”
xmlns:tools=”http://schemas.android.com/tools”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:background=”#48999797″
tools:context=”.MainActivity”>

<TextView
android:id=”@+id/textView”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentStart=”true”
android:layout_alignParentLeft=”true”
android:layout_alignParentTop=”true”
android:layout_centerHorizontal=”true”
android:layout_marginStart=”90dp”
android:layout_marginLeft=”90dp”
android:layout_marginTop=”79dp”
android:text=”Rehbere Kişi Ekle”
android:textColor=”#E91E63″
android:textSize=”30sp”
android:textStyle=”bold” />

<TextView
android:id=”@+id/textView2″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentStart=”true”
android:layout_alignParentTop=”true”
android:layout_marginStart=”47dp”
android:layout_marginTop=”186dp”
android:text=”Kişinin Adı” />

<TextView
android:id=”@+id/textView3″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/textView2″
android:layout_alignParentStart=”true”
android:layout_marginStart=”27dp”
android:layout_marginTop=”34dp”
android:text=”Kişinin Soyadı” />

<EditText
android:id=”@+id/etAd”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentTop=”true”
android:layout_alignParentEnd=”true”
android:layout_alignParentRight=”true”
android:layout_marginTop=”175dp”
android:layout_marginEnd=”69dp”
android:layout_marginRight=”69dp”
android:ems=”10″
android:inputType=”textPersonName” />

<EditText
android:id=”@+id/etSoyad”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentTop=”true”
android:layout_alignParentEnd=”true”
android:layout_alignParentRight=”true”
android:layout_marginTop=”229dp”
android:layout_marginEnd=”69dp”
android:layout_marginRight=”69dp”
android:ems=”10″
android:inputType=”textPersonName” />

<TextView
android:id=”@+id/textView4″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/textView3″
android:layout_alignParentStart=”true”
android:layout_alignParentLeft=”true”
android:layout_marginStart=”45dp”
android:layout_marginLeft=”45dp”
android:layout_marginTop=”28dp”
android:text=”GSM No” />

<EditText
android:id=”@+id/etGsm”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentTop=”true”
android:layout_alignParentEnd=”true”
android:layout_alignParentRight=”true”
android:layout_marginTop=”282dp”
android:layout_marginEnd=”70dp”
android:layout_marginRight=”70dp”
android:ems=”10″
android:inputType=”phone” />

<TextView
android:id=”@+id/textView5″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_below=”@+id/textView4″
android:layout_alignParentStart=”true”
android:layout_centerVertical=”true”
android:layout_marginStart=”38dp”
android:layout_marginTop=”44dp”
android:text=”Kişi Not” />

<EditText
android:id=”@+id/etNot”
android:layout_width=”wrap_content”
android:layout_height=”177dp”
android:layout_below=”@+id/etGsm”
android:layout_alignParentEnd=”true”
android:layout_alignParentRight=”true”
android:layout_centerVertical=”true”
android:layout_marginTop=”14dp”
android:layout_marginEnd=”72dp”
android:layout_marginRight=”72dp”
android:ems=”10″
android:gravity=”start|top”
android:inputType=”textMultiLine” />

<Button
android:id=”@+id/btnKisiEkle”
android:layout_width=”350dp”
android:layout_height=”wrap_content”
android:layout_below=”@+id/etNot”
android:layout_alignParentStart=”true”
android:layout_alignParentLeft=”true”
android:layout_centerHorizontal=”true”
android:layout_marginStart=”28dp”
android:layout_marginLeft=”28dp”
android:layout_marginTop=”20dp”
android:text=”Rehbere Kişiyi Ekle” />

<Button
android:id=”@+id/btnKisiler”
android:layout_width=”345dp”
android:layout_height=”wrap_content”
android:layout_alignParentStart=”true”
android:layout_alignParentLeft=”true”
android:layout_alignParentBottom=”true”
android:layout_marginStart=”31dp”
android:layout_marginLeft=”31dp”
android:layout_marginBottom=”85dp”
android:text=”Tüm Kişiler” />
</RelativeLayout>

MainActivity.java dosyamızda nesneleri ve referanslarını tanımlayalım.
public class MainActivity extends AppCompatActivity {

EditText etAd,etSoyad,etGsm,etNot;
Button btnKisiler,btnKisiEkle;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

etAd = findViewById(R.id.etAd);
etSoyad = findViewById(R.id.etSoyad);
etGsm = findViewById(R.id.etGsm);
etNot = findViewById(R.id.etNot);
btnKisiEkle = findViewById(R.id.btnKisiEkle);
btnKisiler = findViewById(R.id.btnKisiler);

btnKisiEkle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

}
});

btnKisiler.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(),KisilerActivity.class));
}
});
}
}

btnKisiEkle nesnemizin tıklama olayını tanımlayabilmek adına öncelikle yeni bir model sınıf üretmemiz gerekmektedir.

Kisi.java isminde bir sınıf üretip aşağıdakileri yazalım;
package com.serifgungor.room;

import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

@Entity(tableName = “tablo_kisi”)
public class Kisi {
@ColumnInfo(name = “ad”)
String ad;
@ColumnInfo(name = “soyad”)
String soyad;
@ColumnInfo(name = “gsm”)
String gsm;
@ColumnInfo(name = “not”)
String not;
@PrimaryKey(autoGenerate = true)
int kisiId = 0;

@NonNull
@Override
public String toString() {
return ad+” “+soyad+” “+gsm+” “+kisiId;
}
}

Üst satırlarda yazan @ ile başlayan ifadelere Annotation diyoruz, bunlar bize kolaylık sağlayan efektif programlama ile alakalı kavramlardan. Peki bu kavramlar neler ?

@Entity – Room Kütüphanesine ait bir annotation’dur. Bu Anotasyon sayesinde ilgili tablo ismini belirtebiliriz.

@ColumnInfo – Bu anotasyon ise bir alt satırda tipini ve adını belirttiğimiz değişkenin ismini tanımladığımız alanı ifade ediyor. Yani bir nevi kolon ismini belirttiğimiz yerlerdir. name = “deneme” gibi kullanım ise kolonun ismini tanımladığımız alanı ifade ediyor.

@NonNull – Örneğimizde kullanmadık ama NonNull ise boş bırakılamayacak olan alan olduğunu ifade eden bir annotation’dur. Anotasyonlar satır satır üst üste eklenebilir.

@PrimaryKey – İlişkisel veritabanı yönetim sistemlerinde kullanılan Primary Key’den farkı yok. Benzersiz sayıyı temsil ediyor, içerisinde autoGenerate = true ifadesi ise o sayıların birer birer artmasına olanak tanıyor.

Yukarıdaki sınıfta toString metodunu classı adapter’a atacağım zaman satır görüntüsünde tüm detaylarını listelemesi için ekledim.

Şimdi KisiDao.java isminde bir dosya üretelim. (Dao da neyin nesi diyen varsa, Data Access Object veya DAO Pattern diye Google’lasın)
package com.serifgungor.room;

import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import java.util.List;

@Dao
public interface KisiDao {
@Query(“SELECT * FROM tablo_kisi”)
List<Kisi> getTumKisiler();

@Insert
void setKisi(Kisi kisi);
}

Yine üst satırlarda yazan Anotasyonlara bakalım;

interface’in üst satırında yapılan işin Dao olduğunu @Dao ile belirttik.

@Query select sorgusunda bulunup o sorgudan dönen tüm değerleri alt satırdaki metoda gönderdik.

@Insert diyerek bir alt satırda bulunan Kisi değerini temsil ettik.

Bunlar haricinde @Delete ve @Update de kullanabilirsiniz.

Şimdi AppDatabase.java dosyası oluşturup, RoomDatabase sınıfından türetelim, ilgili sınıf abstract class olsun.

AppDatabase sınıfının son hali aşağıdaki gibi olmalı.
package com.serifgungor.room;

import androidx.room.Database;
import androidx.room.RoomDatabase;

@Database(entities = {Kisi.class},version = 1)
public abstract class AppDatabase extends RoomDatabase {

public abstract KisiDao kisiDao();

}

MainActivity.java dosyamızın son hali;
package com.serifgungor.room;

import androidx.appcompat.app.AppCompatActivity;
import androidx.room.Room;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.util.List;

public class MainActivity extends AppCompatActivity {

EditText etAd,etSoyad,etGsm,etNot;
Button btnKisiler,btnKisiEkle;
AppDatabase db;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

etAd = findViewById(R.id.etAd);
etSoyad = findViewById(R.id.etSoyad);
etGsm = findViewById(R.id.etGsm);
etNot = findViewById(R.id.etNot);
btnKisiEkle = findViewById(R.id.btnKisiEkle);
btnKisiler = findViewById(R.id.btnKisiler);
db = Room.databaseBuilder(getApplicationContext(),AppDatabase.class,”kisiler”)
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();

btnKisiEkle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Kisi kisi = new Kisi();
kisi.ad = etAd.getText().toString();
kisi.soyad = etSoyad.getText().toString();
kisi.gsm = etGsm.getText().toString();
kisi.not = etNot.getText().toString();
db.kisiDao().setKisi(kisi);

List<Kisi> kisiler = db.kisiDao().getTumKisiler();
Toast.makeText(getApplicationContext(),”Toplam kişi sayısı: “+kisiler.size(),Toast.LENGTH_LONG).show();

}
});

btnKisiler.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(),KisilerActivity.class));
}
});
}
}

KisilerActivity sayfası üretip, ilgili layout’a tam sayfa genişliğinde 1 adet ListView nesnesi ekleyiniz, ismi listViewKisiler olsun.

KisilerActivity.java dosyamız ise şöyle;
public class KisilerActivity extends AppCompatActivity {

ListView listViewKisiler;
AppDatabase db;
ArrayAdapter<Kisi> arrayAdapter;
List<Kisi> kisiler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_kisiler);

db = Room.databaseBuilder(getApplicationContext(),AppDatabase.class,”kisiler”)
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();

kisiler = db.kisiDao().getTumKisiler();
arrayAdapter = new ArrayAdapter<>(getApplicationContext(),android.R.layout.simple_list_item_1,kisiler);

listViewKisiler = findViewById(R.id.listViewKisiler);
listViewKisiler.setAdapter(arrayAdapter);
}
}

Room Kütüphanesi hakkında daha detaylı bilgi almak için; Android Developers sayfasından ulaşabilirsiniz.

Kullanım zor mu Allah aşkına, bana sorarsanız değil. Zor diyen olursa kızarım, bu makaleyi yazdığım dakikalarda öğrendim Room kütüphanesini, velhasıl kelam kendinize güvenin, iş ilanlarında da sıkça görülebilir. Sınava girmeden önce kopya çeken öğrenci gibi hissettim kendimi ya da Ders notu hazırlarken öğrenen bir öğretmen ve ya İşi işte öğrenen bir çalışan.

Keyifli çalışmalar herkese, kalın sağlıcakla…