Kişisel web sayfamda yazılım, teknoloji ve genel hayat hakkında paylaşımlar yapmayı hedefliyorum.

Room Kütüphanesi Nedir? Nasıl Kullanılır?(Room Persistence Library)

room-flow

Android proje geliştirenlerin yakından tanıdığı SQLite veritabanından gücünü alan Room Kütüphanesi (Room Persistence Library ) Google IO-2017 ile karşımıza çıktı.

RoomDB bizlere,

  • Derleme zamanında hataları ele alma fırsatı
  • SQLite veritabanına daha kolay erişim
  • Diğer mimari yapılarla uyumlu (Örneğin: LiveData, RxJava) bir veritabanı kullanımı sunuyor.
room-architecture

RoomDB yapısına baktığımızda üç büyük bileşenden oluştuğunu görüyoruz.

Entity: Veritabanımızdaki tablolara karşılık gelir. Bir entity sınıfı tabloyu ifade ederken; sınıf içindeki alanlar ise tablomuzun kolonlarına karşılık gelir.

DAO: Tablolarımız üzerinde işlem yapmak için kullandığımız Interface yapısıdır. İlgili metotları burada tanımlarız.

Database: Veritabanımızın Entity ve Dao sınıflarını kullanarak tasarlandığı abstract sınıftır. RoomDatabase sınıfından extend edilir. Veritabanımızın ilk kurulum ayarlarını tanımlayabiliriz.

Gelin şimdi oldukça basit personel kayıt senaryosu üzerinden adım adım bu bileşenleri inceleyerek bir RoomDb kuralım.

Öncelikle projemizin bağımlılıklarına bazı eklemeler yapmalıyız.

dependencies {
***
def room_version = "2.2.4"

implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
}

Gradle dosyalarımızda Best Practices olarak versiyonları bir değişkende tutup tek noktadan kontol etmemiz bizlere avantaj sağlayacaktır.

Daha sonrasında Personel adında bir sınıf oluşturup bu sınıfı entity yani veritabanında tablo olarak kullanmak istiyoruz. Burada bazı annotationlar kullanacağız.

Entity: Bir sınıfın veritabanı tablosu olduğunu belirten ifadedir.

Entity(tableName =”tabloAdi”) kullanımı ile tablomuza istediğimiz ismi verebiliriz. Varsayılan hali sınıfımızın adıdır.

PrimaryKey: Sınıf içindeki bir alanın özel anahtar olduğunu belirtir. autoGenerate = true parametresi ile otomatik artan bir anahtarımız oluşacaktır.

ColumnInfo(name = “kolonAdi”): Kolon isimlerini özelleştirmek istersek bu annotation işimizi halledecektir. Varsayılan durumda ise alan adını otomatik alır.

@Entity
public class Personal {
    @PrimaryKey(autoGenerate = true)
    private int id;
    @ColumnInfo(name = "personalName")
    private String name;
    @ColumnInfo(name = "personalSurname")
    private String surName;
    private String department;
    private int experience;
}

Burasının uzamaması için get-set metotlarını yazmadım. Siz oluşturabilirsiniz.

Şimdi, Personel varlık sınıfımız ile gerçekleştireceğimiz işlemleri belirteceğimiz PersonalDAO interface sınıfımızı oluşturalım.

RoomDb tarafından sağlanan hazır metotları annotationlar kullanarak implemente ediyoruz. Kendimiz spesifik bir sorgu yazmak istersek Query etiketini kullanabiliriz. Eğer çalışma zamanında bir sorgu göndermek istiyorsak RawQuery etiketi bu işi hallediyor.

@Dao
public interface PersonalDAO {
    @Insert
    void insert(Personal personal);
    @Update
    void update(Personal personal);
    @Delete
    void delete(Personal personal);
    @Query("select * from Personal where experience > 10")
    List<Personal> getOldPersonals();
    @RawQuery
    List<Personal> getPersonalByRawQuery(SupportSQLiteQuery query);
}

Bu metotların kullanım senaryoları bu kadar kısıtlı değil ama ben oldukça sade anlatmaya çalışıyorum. Umarım anlaşılır gidiyordur.

Şimdi sıra geldi son büyük bileşen olan database kısmına. Bu bölümde veritabanımızı oluşturan kodlara dokunacağız. AppDatabase isimli bir sınıf oluşturuyorum ben. İsim isteğe bağlı fakat bu sınıfımızın kritik iki noktası var:

  • Abstract Sınıf kullanımı
  • RoomDatabase extend etmeli

Database etiketi içinde entities parametresine varlık sınıflarımızı, version parametresine ise veritabanı versiyonumuzu giriyoruz. Versiyon kısmı migration işlemlerinde önem kazanıyor.
@Database(entities = Personal.class, version = 1)

@Database(entities = Personal.class, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public static final String DATABASE_NAME = "PersonalDB";
    private static AppDatabase instance;
    public abstract PersonalDAO personalDAO();
    static synchronized AppDatabase getInstance(Context context){
        if (instance == null){
            instance =  Room.databaseBuilder(context.getApplicationContext(),AppDatabase.class,DATABASE_NAME)
                    .fallbackToDestructiveMigration()
                    .addCallback(roomCallback)
                    .build();
        }
        return instance;
    }
    private static RoomDatabase.Callback roomCallback = new RoomDatabase.Callback(){
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);
            new PopulateAsyncTask(instance).execute();
        }
    };
    
    private static class PopulateAsyncTask extends AsyncTask<Void,Void,Void> {
        private PersonalDAO personalDAO;
        private PopulateAsyncTask(AppDatabase database){
            personalDAO = database.personalDAO();
        }
        @Override
        protected Void doInBackground(Void... voids) {
            personalDAO.insert(new Personal("PersonalName","PersonalSurname","PersonalDepartment",5));
            personalDAO.insert(new Personal("PersonalName","PersonalSurname","PersonalDepartment",11));
            return null;
        }
    }
}

Kodların içindeki singleton yapısı dikkatinizi çekmiş olabilir. Bu yapı veritabanı işlemlerinde tek bir nesne ile hareket etmemizi sağlayacaktır. Eğer ilk oluşum esnasında veritabanını doldurmak(populate) isterseniz bunu Calback metodlar ile yapabilirken createFromAssetcreateFromFile metotları ile de yapabilirsiniz.

Veritabanı kurulum işlemleri bitti. Gelin şimdi bu metotları nasıl kullanabiliriz örneklere bakalım. Önce nesnelerimize erişelim.

AppDatabase appDatabase = AppDatabase.getInstance(getApplicationContext());
PersonalDAO personalDAO = appDatabase.personalDAO();

Artık personalDAO üzerinden işlemlerimizi çağırabiliriz.

personalDAO.insert(new Personal("PersonalNew","PersonalNew","PersonalNewDepartment",5));
List<Personal> oldPersonals = personalDAO.getOldPersonals();
int userID = oldPersonals.get(1).getId();
personalDAO.getPersonalByRawQuery(new SimpleSQLiteQuery("delete from personal where id = ?",new Object[]{userID}));

Bir sonraki yazıda görüşmek dileğiyle hoşçakalın…

Share

You may also like...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir