LoginSignup
10
10

More than 3 years have passed since last update.

KotlinでRealm(他のDBとの概要比較)

Posted at

kotlinで初めてRealm使ったの行ったことをまとめときます。
初学者の参考になれば

Realmとは

iosやAndroidの端末内で動くデータベースです。

データベース比較(RealmとRoom)

Androidでよく使われるRealmとRoomの簡単な比較をまとめ。
使い分け大事です。

Realm

メリット
・速い
動作はSQLiteよりも早く、
・iosとAndroidともに対応

デメリット
apkファイルを2.5MB増加させる

Room

メリット
・SQLiteデータベースにアクセスする処理がとても簡単に記述できます。
・SQLの中に現れるカラム名のミスなどがコンパイル時にエラーとして検出できることが強みです。
・LiveDataと一緒に使えばデータ変更を検知してUIを更新するような処理がとても簡単に記述できます。

デメリット
Swiftにはない

今回作るアプリ

テキストを入力してボタンを押すとひたすらにRealmに保存されていき、表示するアプリになります。
データの読み込み、追加を学べます。

Gradleの設定

今回Recyclerviewを使うのでそれも追加します。

app/build.gradle

apply plugin: "realm-android"
//省略
dependencies {
    //省略
    //Realm
    implementation 'io.realm:android-adapters:3.1.0'

    //recyclerview
    implementation 'androidx.recyclerview:recyclerview:1.1.0'

}

Realmの初期設定

Applicationクラスを作ります。
アプリを起動した際に最初に動くクラスになります。
何も考えなくていい初期化をします。
Realmの設定をいじることができます。

Application.kt
class Application: Application() {

    override fun onCreate() {
        super.onCreate()

        //Realmの初期化
        Realm.init(this)
        val config = RealmConfiguration.Builder()
            //もともとあったデータを全て削除してくれる(なくても問題ない)
            .deleteRealmIfMigrationNeeded()
            .build()
        Realm.setDefaultConfiguration(config)
    }

}
AndroidManifest.xml
<application
        //追加
        android:name=".Application"
       //省略
        >
    </application>

Modelの作成

DBのモデルを設定する。
アノテーションについてはPrimaryKeyを設定しないと値の変更ができなくなります
また、クラスをopen属性にしないと継承、オーバーライドできないので注意。
Realmで作るときの注意点として、RealmObjectを継承する必要があります。

Model.kt
open class Model : RealmObject() {
    @PrimaryKey
    var id: String = UUID.randomUUID().toString()
    var title: String = ""
}

Adapterの設定

ここで普段のRecyclerViewとは違いRealmならではの部分があります。

はじめにクラスの継承についてRecyclerViewAdapterを使っているとこがRealmを使うとRealmRecyclerViewAdapterになります。
その際にViewHolderだけを指定するのではなく、Modelも指定します。

クラスの引数に関しては、あまり理解出来なかったです。他の記事等みなさんこのような形で書かれていたので、深い理解が出来ませんでした。

Adapter.kt
class Adapter(
    private val context: Context,
    private val List: OrderedRealmCollection<Model>?,
    private val autoUpdate: Boolean
) : RealmRecyclerViewAdapter<Model, Adapter.ViewHolder>(List, autoUpdate) {

次にクラスの中身です。
ここはRecyclerViewの時と変わりありません。

Adapter.kt
    //リストの取得件数
    override fun getItemCount(): Int {
        return List?.size ?: 0
    }
    override fun onCreateViewHolder(viewGroup: ViewGroup, position: Int): ViewHolder {
        val view: View = LayoutInflater.from(context).inflate(R.layout.item, viewGroup, false)

    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val person = List?.get(position)
        holder.textView.text = person?.title
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView = view.textView
    }

最終的な形です。

Adapter.kt
class Adapter(
    private val context: Context,
    private val List: OrderedRealmCollection<Model>?,
    private val autoUpdate: Boolean
) : RealmRecyclerViewAdapter<Model, Adapter.ViewHolder>(List, autoUpdate) {

    override fun getItemCount(): Int {
        return List?.size ?: 0
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, position: Int): ViewHolder {
        val view: View = LayoutInflater.from(context).inflate(R.layout.item, viewGroup, false)

    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val person = List?.get(position)
        holder.textView.text = person?.title
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView = view.textView
    }
}

Activityにセット

MaianActivity.kt
class MainActivity : AppCompatActivity() {

    private val mRealm: Realm by lazy {
        Realm.getDefaultInstance()
    }

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

        val read = readList()

        //btnAddというiDのついたボタンを押した時の処理
        btnAdd.setOnClickListener {
            addList(editText.text.toString())
            //加えた後にreadしないと追加されても表示されないので読み込み処理も書きます。
            read
        }

        //RecyclerViewのAdapter、layoutなどの設定
        val adapter = Adapter(this, read, true)
        recyclerView.setHasFixedSize(true)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = adapter
    }

    //Realmにあるデータを読み込みます。
    fun readList(): RealmResults<Model> {
        return mRealm.where(Model::class.java).findAll()
    }

    //Realmにデータを追加します。
    fun addList(title:String){
        mRealm.executeTransaction {
            var model = mRealm.createObject(Model::class.java , UUID.randomUUID().toString())
            model.title = title
            mRealm.copyToRealm(model)
        }
    }

}

mRealmの変数ですがlazyという委譲プロパティを使って遅延初期化をしています。
これはこの変数が最初に参照されたときに{}内の値をsetして初期化します。

スクショ

Screenshot_20191208_131304_com.example.realmapp.jpg

終わりに

CardViewとDataBindingを付け加えたい(間に合わなかった。)

参考

DBの比較一覧
https://github.com/AlexeyZatsepin/Android-ORM-benchmark
Kotlin+Realm+RecyclerViewを使ってTodoアプリを作る
https://qiita.com/konatsu_p/items/5ab92ebce46c9479876b
KotlinでRealmとRecyclerViewを組み合わせて使ってみる
https://qiita.com/keseran/items/07b01b2dd22a0addd1a3

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10