【Android】DB を使用する ~ Realm 編 ~

 ■ はじめに

https://dk521123.hatenablog.com/entry/2013/10/03/233757

で、SQLiteを取り扱ったが、今回は、 Realm を扱う。

■ Realm

Realm(レルム) = 分野、領域、範囲、部門

 * SQLiteのような軽量データベース
  => SQLiteよりも高速

 公式サイト
https://realm.io/
 ライセンス

 * Apache2.0 (無料。商用利用可能)

■ 使用上の注意

* データ型でサポート外のものもあるので注意

https://realm.io/jp/docs/java/latest/

より抜粋
~~~~
String, Integer, Boolean, Float, Double, Short, Long, Byte, ByteArray and Date
~~~~

詳細

* 以下の関連記事を参照のこと。

https://dk521123.hatenablog.com/entry/2020/07/24/000000

 ■ 初期設定

[1] 「./build.gradle」に
 「classpath "io.realm:realm-gradle-plugin:【バージョン ※】"」を追記し、
    「./app/build.gradle」に「realm-android」を追記する

※ 【バージョン】は、以下のサイトから最新版を確認(今回は「5.4.1」)

https://realm.io/docs/java/latest/

[2] Android Studioの[File]-[Sync Project with Gradle Files]を選択し、
    Realm をダウンロードする

./build.gradle

buildscript {
    ext.kotlin_version = '1.2.50'
    // ... 略 ...
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.4'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "io.realm:realm-gradle-plugin:5.4.1" // ★ Add ★
    }

./app/build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' // ★ Add ★
apply plugin: 'realm-android' // ★ Add ★

 ■ サンプル

 初期化処理 DemoApplication.kt

import android.app.Application
import io.realm.Realm

class DemoApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Realm.init(this)
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
・・・略・・・
    <application
        android:name=".DemoApplication"Add

 処理部分

 * RealmObject を継承する。それにより、「open」を付ける
  => Kotlinは、open付けないと継承できない。
  => Kotlinのデフォルトでは、Javaでのfinal classになる

 * Kotlinの文法については、以下の関連記事を参照のこと。

https://dk521123.hatenablog.com/entry/2020/07/23/000000

【Model】Comment.kt

import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.Required

open class Comment: RealmObject() {
    @PrimaryKey
    var id: Long = 0
    @Required
    var title: String = ""
    var detail: String = ""
}

MainActivity.kt

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import io.realm.Realm
import io.realm.kotlin.createObject
import io.realm.kotlin.where
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    private lateinit var realm: Realm

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

        realm = Realm.getDefaultInstance()
        saveButton.setOnClickListener {
            try {
                realm.executeTransaction {
                    val maxId = realm.where<Comment>().max("id")
                    val targetId = (maxId?.toLong() ?: 0L) + 1L
                    val comment = realm.createObject<Comment>(targetId)
                    comment.title = titleEditText.text.toString()
                    comment.detail = detailEditText.text.toString()
                    Toast.makeText(this, "追加しました. ID : " + targetId.toString(),
                            Toast.LENGTH_SHORT).show()
                }
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
        }
        searchButton.setOnClickListener {
            try {
                val targetId = (targetIdEditText.text.toString().toLong() ?: 1L)
                val comment = realm.where<Comment>()
                        .equalTo("id", targetId).findFirst()
                idResulTextView.setText(comment?.id.toString())
                resultTitleEditText.setText(comment?.title)
                resultDetailEditText.setText(comment?.detail)
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
        }
        updateButton.setOnClickListener {
            try {
                realm.executeTransaction {
                    val targetId = (targetIdEditText.text.toString().toLong() ?: 1L)
                    val comment = realm.where<Comment>()
                            .equalTo("id", targetId).findFirst()
                    comment?.title = resultTitleEditText.text.toString()
                    comment?.detail = resultDetailEditText.text.toString()
                }
                Toast.makeText(this, "更新しました",
                        Toast.LENGTH_SHORT).show()
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
        }
        deleteButton.setOnClickListener {
            try {
                realm.executeTransaction {
                    val targetId = (targetIdEditText.text.toString().toLong() ?: 1L)
                    realm.where<Comment>().equalTo("id", targetId)?.findFirst()?.deleteFromRealm()
                }
                Toast.makeText(this, "削除しました", Toast.LENGTH_SHORT).show()
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        realm.close()
    }
}

 関連記事

DB を使用する ~ SQLite 編 ~
https://dk521123.hatenablog.com/entry/2013/10/03/233757
画面コンポーネント / ListView ~ Realm データを表示 ~
https://dk521123.hatenablog.com/entry/2018/09/02/130212
Kotlin / Realm で英単語帳を作る
https://dk521123.hatenablog.com/entry/2020/07/20/232009
Realm に関するトラブル
https://dk521123.hatenablog.com/entry/2020/07/24/000000
Kotlin ~ 基本編 / クラス ~
https://dk521123.hatenablog.com/entry/2020/07/23/000000