Merhaba,


Bu yazıda Android'de Room kütüphanesi ile SQLite kullanımından bahsedeceğim.


SQLite kısaca dosya şeklinde tutulan bir veritabanıdır. SQLite kullanarak herhangi bir sunucuya ihtiyaç kalmadan, veritabanımızı cihazın içerisinde bulundurabiliriz. Elbette bu yapı her proje için uygun değildir. Örneğin bir günlük uygulaması yaparken kullanmak mantıklı olabilir ancak online bir oyun yaparken kullanmak pek de doğru olmayacaktır. Çünkü veritabanı her kullanıcının cihazında ayrı şekilde oluşacaktır.


Örnek projemizde Kotlin programlama dilini kullanarak, kullanıcının okuduğu kitapların listesini tutmasını sağlayan bir uygulama yapacağız. Projeyi Github üzerinden paylaştım, indirip inceleyebilirsiniz:


Örnek proje linki


İlk olarak Android Studio'da yeni bir proje oluşturuyoruz. Sonrasında build.gradle dosyasını açıp şu satırları ekliyoruz ve Sync Now'a basıyoruz:

apply plugin: 'kotlin-kapt'

...

dependencies {
  implementation 'com.android.support:design:28.0.0' // floating action button eklemek için
  implementation 'android.arch.persistence.room:runtime:1.1.1' // room kütüphanesi için
  kapt 'android.arch.persistence.room:compiler:1.1.1' // room kütüphanesi için
}


Veritabanımızın tablosunu belirtmek adına bir model dosyası oluşturacağız. Bunun için Book adında bir Class oluşturuyoruz:

package com.yusufborucu.roomsample

import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey

@Entity(tableName = "book")
class Book {
    @PrimaryKey(autoGenerate = true)
    var bookId: Int = 0

    @ColumnInfo(name = "name")
    var name: String = ""

    @ColumnInfo(name = "author")
    var author: String = ""

    @ColumnInfo(name = "pageCount")
    var pageCount: Int = 0
}
  • @Entity ile bu Class'ın bir tablo için oluşturulduğunu ve tablo adını (tableName) belirttik.
  • @PrimaryKey ve autoGenerate ile bookId sütununun birincil anahtar ve otomatik artan şekilde olduğunu belirttik.
  • @ColumnInfo ile tablonun diğer sütunlarını (name, author, pageCount) belirttik.


Veritabanımızda yapılacak işlemler için bir Dao (Data access object => Veri erişim nesnesi) oluşturacağız. Bunun için BookDao adında bir Interface oluşturuyoruz:

package com.yusufborucu.roomsample

import android.arch.persistence.room.Dao
import android.arch.persistence.room.Delete
import android.arch.persistence.room.Insert
import android.arch.persistence.room.Query

@Dao
interface BookDao {

    @Query("SELECT * FROM book")
    fun getAllBooks(): List<Book>

    @Insert
    fun addBook(book: Book)
}
  • @Dao ile bu Interface'in veritabanı için gerekli işlemleri içereceğini belirttik.
  • @Query ile veritabanından bir sorgu yapacağımızı belirttik. Sorgu sonucuna, getAllBooks adında, tüm kitapları Book modelimize uygun bir liste şeklinde döndüren bir fonksiyon ile ulaşacağımızı söyledik.
  • @Insert ile tabloya veri ekleyeceğimizi ve bu işlemi addBook fonksiyonu ile yapacağımızı belirttik.


Şimdi de veritabanımızı oluşturacak ve yönetecek sınıfı yazacağız. DatabaseManager adında bir Class oluşturuyoruz:

package com.yusufborucu.roomsample

import android.arch.persistence.room.Database
import android.arch.persistence.room.Room
import android.arch.persistence.room.RoomDatabase
import android.content.Context

@Database(entities = [Book::class], version = 1)
abstract class DatabaseManager : RoomDatabase() {

    abstract fun bookDao(): BookDao

    companion object {
        var INSTANCE: DatabaseManager ?= null

        fun getDatabaseManager(context: Context): DatabaseManager? {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(
                    context.applicationContext,
                    DatabaseManager::class.java,
                    "book-database"
                ).allowMainThreadQueries()
                    .build()
            }
            return INSTANCE
        }
    }
}
  • @Database ile bu Class'ın veritabanı oluşturmak için olduğunu, entities ile tablolarımızı ve version ile de veritabanının versiyonunu belirttik. İleride veritabanında bir değişiklik yapmamız halinde bu version değerini yükseltmeliyiz.


Artık işin görsel tarafına geçelim. Uygulamamız 2 adet ekrandan oluşsun. İlk ekranda eklediğimiz verilerin bulunduğu bir ListView ve ekleme ekranına geçmek için bir FloatingActionButton, ikinci ekranda da veri eklemek için gerekli 3 adet EditText ve kaydetmek için bir Button olsun.


activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/lvBooks"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="0dp"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginEnd="0dp"
        android:layout_marginBottom="0dp"
        app:layout_constraintBottom_toBottomOf="parent"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fabAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        android:src="@drawable/ic_plus"
        app:borderWidth="0dp"/>

</android.support.design.widget.CoordinatorLayout>


MainActivity.kt:

package com.yusufborucu.roomsample

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    var databaseManager: DatabaseManager ?= null
    val books: MutableList<String> = arrayListOf()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        databaseManager = DatabaseManager.getDatabaseManager(this)

        val bookList = getAllBooks()
        bookList!!.forEach {
            books.add(it.name + " - " + it.author + " - " + it.pageCount + " sayfa")
        }

        val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, books)
        lvBooks.adapter = adapter

        fabAdd.setOnClickListener {
            val intent = Intent(this, AddActivity::class.java)
            startActivity(intent)
            finish()
        }
    }

    private fun getAllBooks(): List<Book>? {
        return databaseManager?.bookDao()?.getAllBooks()
    }
}


activity_add.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".AddActivity">

    <EditText
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:ems="10"
        android:id="@+id/etName"
        android:layout_marginStart="8dp"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="120dp"
        app:layout_constraintTop_toTopOf="parent"
        android:hint="Kitabın adını giriniz"/>
    
    <EditText
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:ems="10"
        android:id="@+id/etAuthor"
        android:layout_marginStart="8dp"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginTop="24dp"
        app:layout_constraintTop_toBottomOf="@+id/etName"
        android:hint="Kitabın yazarını giriniz"/>
    
    <EditText
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:inputType="number"
        android:ems="10"
        android:id="@+id/etPage"
        android:layout_marginTop="24dp"
        app:layout_constraintTop_toBottomOf="@+id/etAuthor"
        android:layout_marginStart="8dp"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        android:hint="Kitabın sayfa sayısını giriniz"/>
    
    <Button
        android:text="Kaydet"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/bSave"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginEnd="8dp"
        android:layout_marginTop="72dp"
        app:layout_constraintTop_toBottomOf="@+id/etPage"/>

</android.support.constraint.ConstraintLayout>


AddActivity.kt:

package com.yusufborucu.roomsample

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_add.*

class AddActivity : AppCompatActivity() {

    var databaseManager: DatabaseManager ?= null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_add)

        databaseManager = DatabaseManager.getDatabaseManager(this)

        bSave.setOnClickListener {
            val name = etName.text.toString()
            val author = etAuthor.text.toString()
            val page = etPage.text.toString()

            insertBook(name, author, page.toInt())

            Toast.makeText(applicationContext, "Kitap başarıyla kaydedildi.", Toast.LENGTH_SHORT).show()

            etName.setText("")
            etAuthor.setText("")
            etPage.setText("")
        }
    }

    override fun onBackPressed() {
        val intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
        finish()
    }

    private fun insertBook(name: String, author: String, page: Int) {
        val book = Book()
        book.name = name
        book.author = author
        book.pageCount = page
        databaseManager?.bookDao()?.addBook(book)
    }
}


Uygulamamızın çalışır hali şu şekilde olacaktır:


İlk ekran:


Ekleme ekranı:


Umarım yararlı olmuştur.


İyi çalışmalar...