【Realm】

Primary KeyをAUTO INCREMENTにして登録する方法

データをAUTO INCREMENTで保存する

投稿日 2021/04/25 更新日 2021/09/26


こんにちは。当サイトの管理者「元木皇天」です。

今回はRealmのデータ登録時に、PKをAUTO INCREMENTする方法について解説いたします。

と言いましたが、この記事を読み進める前にあらかじめお伝えしたいことがあります。

RealmではAUTO INCREMENTの機能は搭載されていません。

公式ドキュメントには以下のように記載がされています。

"Auto-incrementing properties: Realm has no mechanism for thread-safe/process-safe auto-incrementing properties commonly used in other databases when generating primary keys. "

参考までにリンクも貼っておきます。

Realm公式リファレンス


というわけで、本記事ではRealmにAUTO INCREMENTを自力で実装する方法について解説いたします。

環境
OS:MacOS Big Sur
Xcode:バージョン12.3
Swift:バージョン5.3
Realm:バージョン10.5.1

参考文献:軽量・高速モバイルデータベース Realm入門

やりたいこと

カラム名がIDでInt型のPrimary keyに、AUTO INCREMENTを設定してデータを登録する。

以下AUTO INCREMENTで生成したデータの表示

AUTO INCREMENTで生成したデータの表示

事前準備

まずは事前準備として、Realmに登録するモデルオブジェクト(一般的DBにおけるテーブル)を作成します。

作成の仕方は過去の記事で紹介しているのでそちらを参考にしてください。

【Realm】SwiftUIにRealmを導入する方法

【Realm】Realmでテーブル(モデル)を作成する方法

【Realm】Primary Key(プライマリーキー)を設定する方法

今回はUserTableというモデルにAUTO INCREMENTでデータを登録を行っていきます。

まず、UserTableモデルは以下のような構造になっています。IDとユーザ名を持つシンプルなモデルです。

import Foundation
import RealmSwift

class UserTable: Object{
    //ユーザID
    @objc  dynamic var ID: Int = 0
    //ユーザ名
    @objc  dynamic var userName: String = ""

    //Primary Keyの設定
    override static func primaryKey() -> String? {
        return "ID"
    }
}

今回はこのIDに対してAUTO INCREMENTを設定してデータを追加するようにします。

AUTO INCREMENTの方法

RealmにAUTO INCREMENTの機能を実装するのはとても簡単です。Insertするデータを以下の条件で作成すればいいだけです。

1. 対象のモデルの全データを取得する
2. 取得した結果の中で一番大きいIDを取り出す
3. 新規InsertするデータのIDに、2で取得した値+1の値を設定する
4. Insertを行う

それでは早速このロジックを作成してみましょう。

ContentViewに実際に作成したコードがこちらになります。(ロジックの説明のため、init()内での実装となります)

import SwiftUI
import RealmSwift

struct ContentView: View {
    var allUser:Results<UserTable>?

    init(){
        let realm = try! Realm() //デフォルトRealmの取得
        allUser = realm.objects(UserTable.self) //全データの取得

        var insertID:Int = 1

        for _ in 0..<5{
            //データがまだ登録されていなかったらIDに1を設定する
            if(allUser != nil && allUser!.count != 0){
                //IDの最大値を取得して+1した値をIDにする
                let num = allUser!.value(forKeyPath: "@max.ID") as! Int
                insertID = num + 1
            }

            //登録するデータの作成
            let user:UserTable = UserTable(value: ["ID" : insertID ,
                                                    "userName" : "user"])
            //データの追加
            try! realm.write{
                realm.add(user, update: .modified)
            }
        }
        allUser = realm.objects(UserTable.self)
    }

    var body: some View {
        Text("登録ユーザ")
        if(allUser != nil){
            ForEach(0..<allUser!.count){id in
                HStack(){
                    Text(String(allUser![id].ID))
                    Text(allUser![id].userName)
                }
            }
        }
    }
}

上記のコードを簡単に解説いたします。

まず初めに"UserTable"のデータを全件取得します。

取得結果を変数"allUser"につめます。

その結果、取得できなかった場合はまだデータが登録されていないということなのでIDに1をセットします。

データが取得できた場合は、そのデータ内のIDの最大値を取得して、それ+1の値をInsertしています。

今回は凡例ということでfor文で5回繰り返しています。init()終了後に画面に追加したデータを表示しています。

実際に動かしてみる

では、先程のコードを実際に動かしてみましょう。

コードをビルドして画面を開くと、無事AUTO INCREMENTされたデータが表示されていることが確認できました。

AUTO INCREMENTで生成したデータの表示

まとめ

RealmでAUTO INCREMENTを実装するには、INCREMENTしたいカラムの最大値+1の値を登録するロジックを作成すれば良い。

参考文献・おすすめ文献