このパートでは、次のことをカバーします:
- Realmとは何ですか
- Realmswift
- 複雑なレルムモデルを作成する
- @objcとdynamicをプロパティで使用する理由
- Realmで一対一と多の関係
- Realmにカスタムenumを格納する方法
- RealmOptionalとは何であり、Swift Optional Atomic Propertyを格納する方法
- 計算されたプロパティは、realmで一時的なプロパティとして動作する方法
- パフォーマンス向上のためにインデックスを作成する方法
- レルム内のオブジェクトをリンクしているもの
- 複雑な述語クエリ
- crud操作
- レルム内のライブ結果とは何ですか
- Realmオブジェクトの変更
Realmは、クロスプラットフォームのモバイルオブジェクトデータベースです。 Core DataやSqliteと比較して、非常に高速で、パフォーマンスが高く、使いやすいです。 バックエンドとしてSqliteを使用するCore Dataと比較して、ストレージメカニズムを使用してオブジェクトをJSONとしてディスクに格納します。 これはクロスプラットフォームのC++で書かれているので、Android、iOS、macOS、または他のプラットフォームでもまったく同じように動作します。
RealmSwift
Realmのほとんどはオープンソースですが、Realmのプラットフォームの背後にある秘密のソースは、c++でゼロから書かれたコアDBエンジンです。 RealmSwiftはObjective-C Realm frameworkのラッパーであり、Objective-C Realm frameworkはRealm Core DBエンジンのラッパーです。
はじめに
このチュートリアルでは、図1に示すように、これらのモデルに取り組んでいきます
ユーザー→それはモデルがuserId
また、passportモデルとのTo-one関係とTodoタスクとのTo-Many関係もあります。 (ユーザーはpassportのみを持ち、多くのtodoタスクを持つことができます)
Passport→ユーザーのpassport情報を含むモデルであり、User
User
オブジェクトの逆バックリンクもあります。div>
ユーザーモデル
図2に示すように、ユーザーモデルを作成し、いくつかのプロパティを追加します。
- まず、
Object
User
Realm Object
。 Realmオブジェクトは基本的に標準データモデルであり、アプリで定義した他の標準データモデルと同様です。 唯一の違いは、それらがレルムの永続性と能力に裏打ちされていることです。 すべてのObject
クラスRealmを調べることで、スキーマを推測できます。 永続化するすべてのモデルは、Objectクラスから継承する必要があります。li> firstName
String
RealmSwift
は、String、Date、DataなどのObjective-C Realmフレームワーク型のラッパーであるため、Objective-CのNSObjectのサブクラスなので、Swiftのオブジェクト型も考慮することができます。 この@objcに加えて、Swiftコード(クラス、メソッド、プロパティなど)が必要なことを意味します。)objective-Cから見えるようにするには、dynamicはObjective-C dynamic dispatchを使用することを意味します。 データベースレルムで簡単なswiftオブジェクトストアを作成するには、objective-C動的ディスパッチ機能を使用してフードの下で作業を行いますuserId
userId
primarykey
主キーを作成します。 このメソッドのデフォルトの実装はnilを返します。 注意userId
は、客観的なCレルムのラッパーであるため、客観的なCプリミティブInt型として機能しますpassport
プロパティは、別のレルムオブ 私たちは、パスポートモデルとのTo-One関係を作成しました。 あるrealmオブジェクトが別のrealmオブジェクトを指している関係/オブジェクトへのリンク。 別のRealmオブジェクトとのリレーションシップを作成する場合、そのプロパティの型は省略可能でなければなりません。 パスポートの変数ポインタ参照では、Passport
オブジェクトはprivateUserType
UserType
UserTypeはswift enumなので、Realmに直接格納することはできません。 すべてのcase値には、caseの名前と一致する暗黙的に割り当てられた生の値があります。 この生の値を使用して、EnumオプションをRealmでInt
として永続化します。 しかし、クライアントは計算された列挙型プロパティにアクセスしており、内部の列挙型の生の値/原子値は、クライアントには表示されないデータベースに格納されています。- 文字列、NSDate、およびNSDataプロパティは、標準のSwift構文を使用して、オプションまたは非オプションとして宣言できます。オプションの数値型は、RealmOptionalを使用して宣言されます。 RealmSwiftはObjective C Realmのラッパーであり、Objective CにはオプションのIntがないため、RealmはこのシナリオでRealmOptional型を作成しました。 すべてのObjective Cプリミティブ型は、Optionalを使用してSwiftで必要とするRealmOptionalを使用する必要があります。 これは、動的プロパティの動的ディスパッチに使用されるObjective Cランタイムではジェネリックプロパティを表すことができず、常にletで宣言する必要があ Realmクラスなので、Realm persistオブジェクトが持っているすべての機能を持っています。 図2に示すように、
isEmailSubscriptionEnable
RealmOptional
Boolは、参照型であるため、letで使用したnilであり、将来アドレスを変更したくないこ - 図2に示すように、ユーザーはRealm Todoオブジェクトのコレクションである多くのtodoを持つことができます。 Realmオブジェクトインスタンスのコレクションを保持するRealmクラスとしてリストします。 Todoモデルと多対多の関係を作成しました。 1つのrealmオブジェクトがrealmオブジェクトのコレクションを指すto-manyリレーションシップ。 通常のSwift配列を使用してオブジェクトのレルムコレクションを格納すると、例外が発生します。 注:RealmOptional Listのように、すべての組み込み機能を持つRealmクラスなので、動的および@objcキーワードとして宣言することはできません。 Listは、組み込みメソッドやインデックス付き添字を使用したオブジェクトへのアクセスのためのArrayと非常によく似ています。 あなたが見るようにリストが入力され、すべてのオブジェクトが同じタイプでなければなりません
isUserHasTodos
は計算されたswiftプロパティであり、ユーザーが行うかどうかのタスクがある場合に返されるレルムデータベースには格納されません。- 最後に、インデックス付きプロパティとして
userId
firstName
indexedProperties
静的メソッドをオーバーライドすることにより、文字列形式のプロパティの配列を提供します。 データベースをフィルタリングまたはクエリするときのアクセス時間を改善するために、プロパティにインデックスを付けます
passport model
図3に示すように、いくつかのプロパティを持つpassportモデルを作成しました
passportNumber
expiryDate
@objc
dynamic
キーワードを使用して、レルムにフードマジックの下であなたのことを伝えるpassport
User
User
passport
オブジェクト参照を持っている我々は、passportオブジェクトはまた、このパスポートを持っているユーザーを知っているかどうか、このpassportに関連付けられているユーザーへの参照を持っています。 つまり、PassportにofUser
プロパティを作成し、Passportオブジェクトを割り当てるすべてのユーザーオブジェクトの参照を持つPassportにpassport
プロパティ。 コアデータでは、それは逆関係と呼ばれています。 その動的なコレクションは、現在のオブジェクトにリンクする人を示します。
As shown in Figure 4 we created Todo
Realm model with has a backlink to the all the users pointing to particular task .div>
モデル/スキーマの作成が完了し、実際のcrud操作を行う時間が来ました
オブジェクトをレルムに追加
最初に概念をクリアし、レルムにオブジェク Realmインスタンスを介してデータベースにアクセスできる唯一の方法。 Realm
インスタンス(“A Realm”とも呼ばれます)は、レルムデータベースを表します。レルムは、ディスク(init(path:)
Configuration
Realm
インスタンスはスレッドセーフではなく、スレッド間で共有したり、キューをディスパッチしたりすることはできません。 Realmにアクセスするスレッドごとに、新しいインスタンスを構築する必要があります。新しいアプリであり、データベースにオブジェクトが格納されていないため、図5に示すようにrealm.isEmpty
は、コンソールに印刷されたようにデータベースが空であることを意味します
図7に示すように、最終的にrealmデータベースにオブジェクトを挿入します。 DBへのカスケード挿入を実行しました。
注意:オブジェクトへのすべての変更(追加、変更、削除)は、書き込みトランザクション内で行う必要があります。Realmの書き込み操作は、非同期ではなく、同期的でブロック的なものです。 スレッドAが書き込み操作を開始した場合、スレッドBはスレッドAが終了する前に同じレルムで書き込み操作を開始します。 書き込み操作は常に自動的に更新されるため、競合状態は作成されません。 書き込み操作は、ディスク領域が不足しているようなエラーをスローする可能性があります
- レルムにUserを追加しました。passportとtodosを参照しているため、これらのオブジェクトもレルムに追加されます。
- アンマネージオブジェクトをrealmに追加することで、これらのオブジェクトをコンソールに示すように管理しました。 これで、passportはUserオブジェクトにもアクセスできます。 これでデータベースは空になりません
- write transactionブロックに追加する必要があるオブジェクトを挿入し、Realmインスタンスのaddメソッドを使用してrealmに追 ここで、
userId = 1
を持つユーザーの同じ主キーを持つ別の別のオブジェクトをレルムに別のオブジェクトとして追加しようとすると、例外がトリガーされます
オブジェクトの物理的なストアを確認
デバッガ出力でこのコマンドを実行すると、データが格納されているレルムファイルのアドレスが取得されます
オープン
オープン
オープン
オープン
オープン
オープン
default.realm
realm studioの
realm studioは、realmデータベースとrealmプラットフォームを簡単に管理できるように構築されたpremiere開発者ツールです。 Realm Studioを使用すると、ローカルおよび同期されたRealmを開いて編集したり、任意のRealm Object Serverインスタンスを管理したりすることができます。 Mac、Windows、またはLinux用に今すぐダウンロードしてください。div>
図10に示すように、実際に格納されたデータ。 あなたは疑問に思うかもしれませんArticle
Person
私のプロジェクトクラスの中にはモデルを作成す アプリケーションが実行されると、Realmはアプリとフレームワークのすべてのクラスをイントロスペクトし、RealmのObjectクラスをサブクラス化するクラスを見つけます。 これらのクラスのリストは、ディスクまたはメモリ内に永続化されるデータスキーマであると見なされます。div>
レルムからオブジェクトをフェッチ
レルムからすべてのユーザーレコードをフェッチするプロセスは、次のタスクを持っています
- レルムデータベースのインスタンスを取得し、それがスローすることができます:an
NSError
init()
を呼び出すと作成されます - レルムに格納されている指定された型のすべてのオブジェクdiv>
ユーザーをフェッチしました インデックス付きプロパティでもある主キーからのレコードなので、この主キーを持つオブジェクトが存在しない可能性があるため、オプショ 主キーはInt
String
String.
レルムデータベース内の特定のオブジェクトを一意主キー値が特定のオブジェクトに設定されると、それを変更することはできません。div>
示されているように、いくつかの述語を使用してフィルタリングしました。
- フィルタ→に等しい値に一致します
- フィルタ大文字と小文字を区別しません→に等しい値に一致します大文字と小文字を区別しません
- {1,2,3}フィルタ→値のリストから値に一致します。
- filter→firstNameの値がaで始まる場合に一致します。
- filter→firstName value conatinsがliの場合に一致します。
- Passportオブジェクトを持つ述語passport number==’pass1’を持つユーザーをフィルタリングしたい
- Todosオブジェクトを持つ述語tdodo contains details==’Need ot create RxSwift blog’を持つユーザーをフィルタリングしたい
高度なクエリについては、https://academy.realm.io/posts/nspredicate-cheatsheet/https://academy.realm.io/posts/nspredicate-cheatsheet/https://academy.realm.io/posts/nspredicate-cheatsheet/https://academy.realm.io/posts/nspredicate-cheatsheet/https://academy.realm.io/posts/nspredicate-cheatsheet/https://academy.realm.io/posts/nspredicate-cheatsheet/nspredicate cheatsheet
注:”一時的な(計算された)プロパティ”と呼ばれるものは、レルムは”無視されたプロパティ”と呼ばれます。 これらはほとんどの場合、Realmによって無視されるプロパティなので、dbファイルに保存されず、書き込みトランザクションの外部で変更することがでただし、これはまた、クエリなどの無視されないプロパティの多くの機能の恩恵を受けないことを意味します。 (querying for Realm objects can only be done with non-computed, Realm-persisted properties)
As shown in Figure 14 we sorted results with the firstName
property on User model
ライブ結果
Realmセクションからのフェッチに関する最後のトピック
Realm結果セットは常に最新の最新データを返します。 結果のデータは古くなることはありません。 これは、ディスクから結果をリロードしたり、何らかの方法でメモリ内のデータを手動で更新したりする必要がないことを意味します。
図15に示すように、新しいユーザーを取得し、realm.objects
メソッドを使用してフェッチしませんでした代わりに、新しく追加されたオブジェク コアデータの背景から来た場合は、スタックからオブジェクトを再度取得する必要があります
読み取りと書き込みは、プロジェ Realmオブジェクトは常に最新のものであるため、アプリ内の各クラスはビジネスロジックに焦点を当て、古いデータやキャッシュされたデータの概念を忘div>
図15レルム上のオブジェクトを変更
図16に示すように、主キーを変更しており、”主キーはオブジェクトが挿入された後に変更できません。”主キーを更新できないため例外です。 Realm Docsから主キーがレルムに追加された場合、主キーは変更できません。 回避策→オブジェクトを削除して再挿入するか、stackoverflowでこの質問を参照してください
図16 図17に示すように、write transactionブロックの外部でrealmからフェッチされたオブジェクトを変更することはできませんこの外部で変更しようとすると、rlmrealmインスタ”
Figure 17 As shown in Figure 18 as we modify object in
write
transaction block it will persist that object into the disk as well as shown in Figure 19default.realm
file now has a updatedfirstName
value of UserDiv>