【初学者向け】AndroidでRealmを実装する

# はじめに
[Realmの公式ドキュメント](https://realm.io/jp/docs/java/latest/)を更に実装しやすくするための記事です。

# 準備
Projectの`build.gradle`に下記を加えます。

```gradle
dependencies {
        classpath "io.realm:realm-gradle-plugin:3.5.0"
}
```

下記のようになればOKです。

```build.gradle
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.4'
        classpath "io.realm:realm-gradle-plugin:3.5.0"
    }
}

...
```

次にAppの`build.gradle`に下記を加えます。

```gradle
apply plugin: 'realm-android'
```

下記のようになればOKです。

```build.gradle
apply plugin: 'com.android.application'
apply plugin: 'realm-android'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "***"
        minSdkVersion 21
        targetSdkVersion 28

...
```

また、アプリの起動時にRealmを初期化する必要があります。
今回は`MainActivity`が最初のページなので、`onCreate`に初期化処理`Realm.init()`を書きます。
また、`Realm`のインスタンスは`Realm.getDefaultInstance()`で指定します。
以下のようになればOKです。

```MainActivity.java
...

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

    Realm realm = Realm.getDefaultInstance();
}

...
```

# 保存するモデルを作る

Realmにはモデル単位でデータを保存していきます。
`RealmObject`を継承したモデルを作成しましょう。

```SampleModel.java
import io.realm.RealmObject;

public class SampleModel extends RealmObject {
    private String name;
    private int age;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return this.age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
```

ここからはこのモデルを使っていきます。

# データを新規保存する
保存処理を記述する時は`.beginTransaction()`,`.commitTransaction()`の間に記述します。
また、新規保存時はRealm経由でモデルをインスタンス化します。

| Name | Age |
|:--|--:|
| GODIVA | 21 |
例えば下記のようなデータを保存する場合は以下のようになります。

```MainActivity.java
...

realm.beginTransaction();
SampleModel model=realm.createObject(SampleModel.class);
model.setName("GODIVA");
model.setAge(21);
realm.commitTransaction();

...
```

# データを全て読み込む
読み込みたいデータモデルを指定して読み込みます。
`RealmQuery`で読み込むデータモデルの情報を持ち、`RealmResults`で実際にデータを取得します。
保存されてるデータを全て読み込む場合は以下のようになります。

```MainActivity.java
...

RealmQuery<SampleModel> query = realm.where(SampleModel.class);
RealmResults<SampleModel> result = query.findAll();
        
for (int i=0;i<result.size();i++){
    System.out.println(result.get(i).getName());
    System.out.println(result.get(i).getAge());
}

...
```

現在は上記のデータしか保存されていないため、以下のような出力になります。

```:Logcat
->

I/System.out: 
GODIVA
21
```

# 特定のデータのみ読み込む
データが一つでは検索の意味がないため、加えて複数のデータを保存しておきます。
GODIVAとIEKEIは同い年にします。

| Name | Age |
|:--|--:|
| GODIVA | 21 |
| IEKEI | 21 |
| NATTO | 64 |

```MainActivity.java
...

realm.beginTransaction();

SampleModel model=realm.createObject(SampleModel.class);
model.setName("GODIVA");
model.setAge(21);

SampleModel model2=realm.createObject(SampleModel.class);
model2.setName("IEKEI");
model2.setAge(21);

SampleModel model3=realm.createObject(SampleModel.class);
model3.setName("NATTO");
model3.setAge(64);

realm.commitTransaction();

...
```

先程と同じように`RealmQuery`を作成します。
作成した`RealmQuery`に検索の情報を付加することで特定のデータのみ取得します。
`age = 21`のデータのみ取得する場合は、以下のようにします。

```MainActivity.java
...

RealmQuery<SampleModel> query = realm.where(SampleModel.class);
query.equalTo("age",21);
RealmResults<SampleModel> result = query.findAll();
        
for (int i=0;i<result.size();i++){
    System.out.println(result.get(i).getName());
    System.out.println(result.get(i).getAge());
}

...
```

```
->

I/System.out:
GODIVA
21
IEKEI
21
```

# データを上書き保存する
既に保存されてるデータを上書きしたい場合は、まず上書きするデータを取得します。
データの更新を行うので、保存時と同様に`.beginTransaction()`,`.commitTransaction()`の間に記述します。
下記のコードでは`name = GODIVA`で検索して出てきた一人目の`age`を100歳に上書きしています。

```MainActivity.java
...

RealmQuery<SampleModel> query = realm.where(SampleModel.class);
query.equalTo("name","GODIVA");
RealmResults<SampleModel> result = query.findAll();

realm.beginTransaction();
result.get(0).setAge(100);
realm.commitTransaction();        

...
```

再度データを取得すると確認できます。

```
->

I/System.out:
GODIVA
100
```

`age = 21`の全員の`name`を「ラーメン」にする場合は以下のようにします。

```MainActivity.java
...

RealmQuery<SampleModel> query = realm.where(SampleModel.class);
query.equalTo("age",21);
RealmResults<SampleModel> result = query.findAll();

realm.beginTransaction();
for (int i=0;i<result.size();i++){
    result.get(i).setName("ラーメン");
}
realm.commitTransaction();        

...
```

全員ラーメンになりましたか？

```
->

I/System.out:
ラーメン
21
ラーメン
21
```