CRUD-Operation mit RealmSwift Teil 1

In diesem Teil behandeln wir:

  1. Was ist Realm
  2. RealmSwift
  3. Erstellen eines komplexen Realm-Modells
  4. Warum wir @objc und dynamic in Property verwenden
  5. Zu-Eins- und Zu-Viele-Beziehung im Realm
  6. Wie man benutzerdefinierte Enumerationen im Realm speichert
  7. Was ist RealmOptional und wie man eine optionale atomare Eigenschaft speichert
  8. Wie funktioniert eine berechnete Eigenschaft als transiente Eigenschaft im Realm
  9. Indizierung zur Leistungssteigerung
  10. Was ist das Verknüpfen von Objekten im Realm
  11. Komplexe Prädikatabfragen
  12. CRUD-Operation
  13. Was sind Live-Ergebnisse im Realm
  14. Dinge vermieden, wenn Realm-Objekte ändern

Realm ist eine plattformübergreifende mobile Objektdatenbank. Es ist sehr schnell, performant und einfach zu bedienen im Vergleich zu Core Data und Sqlite. Es verwendet seinen Speichermechanismus, um Objekte als JSON auf der Festplatte zu speichern, im Vergleich zu Core Data, das Sqlite als Backend verwendet. Es ist in plattformübergreifendem C ++ geschrieben und funktioniert daher auf Android, iOS, macOS oder jeder anderen Plattform genauso.

RealmSwift

Der größte Teil von Realm ist Open Source, aber die geheime Sauce hinter der Realm-Plattform ist die Kern-DB-Engine, die in C ++ von Grund auf neu geschrieben wurde. RealmSwift ist ein Wrapper um das Objective-C Realm Framework und Objective-C Realm Framework ist ein Wrapper um Realm Core DB Engine.

Erste Schritte

In diesem Tutorial werden wir an diesen Modellen arbeiten, wie in Abbildung 1 gezeigt

Benutzer → Es ist ein Modell, das Benutzerinformationen enthält, in denen userId es ist primär. Es hat auch eine Eins-zu-Eins-Beziehung zum Passport-Modell und zu viele Beziehungen zu Todo-Aufgaben. (Benutzer kann nur einen Pass haben und viele Aufgaben haben)

Passport → Es ist ein Modell, das Passinformationen eines Benutzers enthält und auch einen Reverse-Back-Link von User Objekt.

Todo → Es ist ein Modell enthält Aufgaben eines Benutzers und hat auch einen Reverse-Back-Link von User Objekt.

Abbildung 1

Benutzermodell

Wie in Abbildung 2 gezeigt, haben wir ein Benutzermodell erstellt und einige Eigenschaften hinzugefügt:

  1. Zuerst erben wir User Klasse von Object wodurch es Realm Object . Realm-Objekte sind im Grunde ein Standarddatenmodell, ähnlich wie jedes andere Standarddatenmodell, das Sie in Ihren Apps definiert haben. Der einzige Unterschied besteht darin, dass sie durch ihre Ausdauer und Fähigkeiten unterstützt werden. Wenn Sie sich alle Object ansehen, können Sie auf Ihr Schema schließen. Jedes Modell, das Sie beibehalten möchten, müssen Sie von der Objektklasse erben.
  2. firstName speichert den Vornamen des Benutzers als String. Da RealmSwift ein Wrapper um das Objective-C-Realm-Framework ist, sind Typen wie String, Date und Data Unterklassen von NSObject in Objective-C, sodass Sie sie auch in Swift als Objekttypen betrachten können. Darüber hinaus bedeutet @objc, dass Sie Ihren Swift-Code (Klasse, Methode, Eigenschaft usw.), um von Objective-C aus sichtbar zu sein, während dynamic bedeutet, dass Sie Objective-C dynamic dispatch verwenden möchten. Um einfache Swift-Objektspeicher im Datenbankbereich zu erstellen, wird die dynamische Dispatch-Funktion von Objective-C verwendet, um unter der Haube zu arbeiten
  3. userId speichert die Benutzer-ID, die als Primärschlüssel fungiert. Sie können eine der Eigenschaften Ihres Objekts als Primärschlüssel festlegen. Normalerweise Eigenschaft, die sich eindeutig identifiziert, das ist ein Hauptkandidat für einen Primärschlüssel. Es hilft Ihnen, eine schnelle Suche oder Bearbeiten von Objekten in einer Datenbank. Wie in Abbildung 2 gezeigt, machen wir userId Primärschlüssel durch Überschreiben primarykey statische Funktion. Die Standardimplementierung dieser Methode gibt null zurück. Hinweis userId fungiert als Objective C primitive Int Typ, da es ein Wrapper um Objective C Realm ist
  4. passport Eigenschaft speichert die Benutzerpassinformationen, die ein anderes Realm-Objekt sind. Wir haben eine Eins-zu-Eins-Beziehung zum Passport-Modell aufgebaut. Eins-zu-Eins-Beziehung / Objekt-Verknüpfung, bei der ein Realm-Objekt auf ein anderes Realm-Objekt zeigt. Wenn Sie eine Beziehung zu einem anderen Realm-Objekt erstellen, muss dessen Eigenschaft einen optionalen Typ haben. In der Variablenzeigerreferenz von Passport Objekt speichert
  5. privateUserType ist die Wrapper-Eigenschaft von UserType Da UserType swift enum ist, können wir nicht direkt auf Realm speichern. Alle Fallwerte hätten einen implizit zugewiesenen Rohwert, der dem Namen des Falls entspricht. Sie verwenden diesen Rohwert, um die Enum-Optionen als Int in Realm beizubehalten. Der Client greift jedoch auf die berechnete Enum-Eigenschaft zu und unter der Haube wird der Rohwert / Atomwert der Enum in der Datenbank gespeichert, die für den Client nicht sichtbar ist.
  6. Die Eigenschaften String, NSDate und NSData können mit der Standard-Swift-Syntax als optional oder nicht optional deklariert werden.Optionale numerische Typen werden mit RealmOptional deklariert. Da RealmSwift ein Wrapper um Objective C Realm ist und es in Objective C kein optionales Int gibt, hat Realm für dieses Szenario den Typ RealmOptional erstellt. Alle Objective C primitiven Typ erfordern in Swift mit Optional müssen Sie RealmOptional verwenden. Hinweis: RealmOptional-Eigenschaften können nicht als dynamic und @objc Schlüsselwort deklariert werden, da generische Eigenschaften nicht in der Objective C-Laufzeit dargestellt werden können, die für den dynamischen Versand dynamischer Eigenschaften verwendet wird und immer mit let deklariert werden sollte. Da es sich um eine Realm-Klasse handelt, verfügt sie über alle Funktionen, die Realm und Objekt haben. Wie in Abbildung 2 gezeigt isEmailSubscriptionEnable wir deklarieren als RealmOptional Bool bedeutet, dass es null sein kann, das wir mit let verwendet haben, da es ein Referenztyp ist und wir nicht möchten, dass sich seine Adresse in Zukunft ändert.
  7. Wie in Abbildung 2 gezeigt, kann der Benutzer viele Todos haben, die eine Sammlung von Realm-Todo-Objekten sind. Liste als Realm-Klasse Sammlung der Realm-Objektinstanzen zu halten. Wir haben eine To-Many-Beziehung mit dem Todo-Modell erstellt. Zu-Viele-Beziehung, in der ein Realm-Objekt auf die Sammlung des Realm-Objekts zeigt. Wenn Sie ein normales Swift-Array zum Speichern einer Realm-Objektsammlung verwenden, erhalten Sie eine Ausnahme. Hinweis: Wie RealmOptional kann List nicht als dynamic und @objc Schlüsselwort deklariert werden, da es sich um eine Realm-Klasse mit allen integrierten Funktionen handelt. List ist Array für integrierte Methoden und den Zugriff auf Objekte mithilfe indizierter Subskription sehr ähnlich. Liste, wie Sie sehen, ist typisiert und alle Objekte sollten vom gleichen Typ sein
  8. isUserHasTodos ist eine berechnete Swift-Eigenschaft und wird nicht in der Realm-Datenbank gespeichert, die zurückgegeben wird, wenn der Benutzer einige Aufgaben zu erledigen hat oder nicht.
  9. Schließlich machen wir userId und firstName als indizierte Eigenschaften. Durch Überschreiben der indexedProperties statischen Methode stellen wir ein Array von Eigenschaften in Zeichenfolgenform bereit. Wir indizieren auf Eigenschaften, um die Zugriffszeiten beim Filtern oder Abfragen der Datenbank zu verbessern

Abbildung 2

Passmodell

Wie in Abbildung 3 gezeigt, haben wir ein Passmodell mit den wenigen Eigenschaften erstellt

  1. passportNumber speichert die Passinformationen und expiryDate speichert das Ablaufdatum des Passes, den wir diese Eigenschaften zu speichern, deshalb haben wir verwenden Sie @objc mit dynamic Schlüsselwort realm zu sagen, tun Sie Ihre unter der Haube Magie
  2. Wir haben passport Eigenschaft auf User Modell, das bedeutet User Objekt haben ihre passport Objektreferenz Was ist, wenn wir wollen passport Objekt auch wissen, welcher Benutzer diesen Pass hat / einen Verweis auf den Benutzer hat, der diesem Pass zugeordnet ist. Wir haben die Backlinks mit LinkingObjects erstellt, was bedeutet, dass wir die ofUser -Eigenschaft in Passport erstellt haben, die eine Referenz aller Benutzerobjekte enthält, die das Passport-Objekt in seiner passport -Eigenschaft zuweisen. In Core Data wird es als inverse Beziehung bezeichnet. Es ist eine dynamische Sammlung, die Ihnen mitteilt, wer mit dem aktuellen Objekt verknüpft ist.

Figure 3

As shown in Figure 4 we created Todo Realm model with has a backlink to the all the users pointing to particular task .

Abbildung 4

Wir haben die Modell- / Schemaerstellung abgeschlossen und jetzt ist es an der Zeit, eine tatsächliche CRUD-Operation durchzuführen

Objekt zum Realm hinzufügen

Wir klären zuerst ein Konzept, dann können wir problemlos Objekte im Realm hinzufügen

Wie in Abbildung 5 gezeigt, erhalten wir zunächst eine Instanz des Standardwerts Realm, indem wir sie ohne Argumente initialisieren. Die einzige Möglichkeit, über die Realm-Instanz auf die Datenbank zuzugreifen. Eine Realm -Instanz (auch als „Realm“ bezeichnet) stellt eine Realm-Datenbank dar.Realms können entweder auf der Festplatte (siehe init(path:)) oder im Speicher (siehe Configuration) gespeichert werden. Realm Instanzen sind nicht threadsicher und können nicht über Threads oder Dispatch-Warteschlangen hinweg gemeinsam genutzt werden. Sie müssen für jeden Thread, in dem auf einen Realm zugegriffen wird, eine neue Instanz erstellen.

Wie in Abbildung 5 gezeigt, da es sich um eine neue App handelt und kein Objekt in der Datenbank gespeichert wurde realm.isEmpty gibt true bedeutet, dass die Datenbank leer ist, wie auf der Konsole gedruckt

Abbildung 5

Wie in Abbildung 6 gezeigt, haben wir eine Reihe von Aufgaben ausgeführt

  1. Wir erhalten die Instanz von Realm Datenbank
  2. Passport

und drei Aufgaben als todos

  • Erstellt User Objekt und weisen Passport und todos zu. Zusätzlich zu dieser initialisierten optionalen Realm-Eigenschaft, die isEmailSubscriptionEnable und Usertype enum mit Gold-Mitgliedschaft
  • ist, wie in Abbildung 6 gezeigt, ist die Realm-Datenbank immer noch leer und das inverse Beziehungs- / Verknüpfungsobjekt funktioniert auch nicht, da wir diese Objekte nicht zum Realm hinzugefügt haben. Realm-Objekte (User, Passport, Todo) können wie normale Swift-Objekte instanziiert und als nicht verwaltete Objekte (dh noch nicht zu einem Realm hinzugefügt) verwendet werden. Um diese Objekte von Realm verwalten zu lassen, müssen Sie sie in Realm hinzufügen

    Abbildung 6

    Wie in Abbildung 7 gezeigt, fügen wir schließlich das Objekt in die Realm-Datenbank ein. Wir haben Cascading Insert in die DB durchgeführt.

    Hinweis: Alle Änderungen an einem Objekt (Hinzufügen, Ändern und Löschen) müssen innerhalb einer Schreibtransaktion erfolgen.Realm-Schreiboperationen sind synchron und blockierend, nicht asynchron. Wenn Thread A eine Schreiboperation startet und Thread B eine Schreiboperation auf demselben Realm startet, bevor Thread A beendet ist, muss Thread A seine Transaktion beenden und festschreiben, bevor die Schreiboperation von Thread B stattfindet. Schreibvorgänge werden immer automatisch aktualisiert, sodass keine Race Condition erstellt wird. Schreiboperation kann Fehler auslösen, wie der Speicherplatz knapp wird

    1. Wir haben Ihrem Realm einen Benutzer hinzugefügt, und da er auf Passport und todos verweist, werden diese Objekte auch zum Realm hinzugefügt.
    2. Durch Hinzufügen eines nicht verwalteten Objekts zu realm haben wir diese Objekte jetzt verwaltet, wie in der Konsole gezeigt. Jetzt können Sie auch auf das Benutzerobjekt zugreifen. Jetzt ist unsere Datenbank nicht mehr leer
    3. Wir fügen endlich ein Objekt in die Datenbank ein, da wir ein Objekt einfügen, das wir im Schreibtransaktionsblock hinzufügen müssen, und wir fügen es dem Realm hinzu, indem wir die Add-Methode für die Realm-Instanz verwenden. Wenn nun versucht wird, ein anderes separates Objekt mit demselben Primärschlüssel des Benutzers mit userId = 1 als separates Objekt zum Realm hinzuzufügen, wird eine Ausnahme ausgelöst

    Abbildung 7

    Überprüfen Sie den physischen Speicher des Objekts

    Wenn Sie diesen Befehl am Debugger-Ausgang ausführen, erhalten Sie die Adresse der Datei, in der Ihre Daten gespeichert sind

    Abbildung 8

    Öffnen in Realm Studio
    Realm Studio ist unsere Premiere Entwickler-Tool, gebaut, so dass Sie ganz einfach die Realm-Datenbank und Realm-Plattform verwalten können. Mit Realm Studio können Sie lokale und synchronisierte Realms öffnen und bearbeiten sowie jede Realm-Objektserverinstanz verwalten. Laden Sie es jetzt für Mac, Windows oder Linux herunter.

    Abbildung 9

    Wie in Abbildung 10 Daten tatsächlich gespeichert. Sie fragen sich vielleicht Article und Person Klasse auch dort, weil in einigen meiner Projektklasse Modelle Person und Artikel erstellen. Wenn die Anwendung ausgeführt wird, überprüft Realm alle Klassen in Ihrer App und Ihren Frameworks und findet die Klassen, die die Objektklasse von Realm unterklassen. Die Liste dieser Klassen wird als Ihr Datenschema betrachtet, das auf der Festplatte oder im Arbeitsspeicher beibehalten wird.

    Abbildung 10

    Objekt aus Realm abrufen

    Der Prozess des Abrufs aller Benutzerdatensätze aus Realm hat folgende Aufgaben

    1. Wir erhalten die Instanz der Realm-Datenbank und sie kann Folgendes auslösen: Ein NSError wenn der Realm nicht initialisiert werden konnte. Standard-Realm wird erstellt, wenn wir init() ohne Parameter aufrufen
    2. Aufgerufene objects-Methode in der Realm-Datenbank, die alle Objekte des angegebenen Typs zurückgibt, die im Realm gespeichert sind, und ein Ergebnis mit allen Objekten zurückgibt, wie in Abbildung 11 gezeigt
    3. Gedrucktes Objekt auf der Konsole, um Daten zu validieren, ist da und die Verknüpfung von Objekten funktioniert einwandfrei

    Abbildung 11

    datensatz von seinem Primärschlüssel, der auch eine indizierte Eigenschaft ist, sodass wir das optionale Benutzerobjekt erhalten, da ein Objekt mit diesem Primärschlüssel möglicherweise nicht vorhanden ist. Der Primärschlüssel kann Int oder String sein. Die Empfehlung ist, String. zu verwenden, um bestimmte Objekte in einer Realm-Datenbank eindeutig zu identifizieren.Sobald ein Primärschlüsselwert für ein bestimmtes Objekt festgelegt wurde, kann er niemals geändert werden.

    Abbildung 12

    Wie gezeigt, haben wir mit einem Prädikat gefiltert Hier ist die Liste der Operatoren, die wir verwendet haben

    1. filter → entspricht Werten gleich
    2. filter case insensitive → entspricht Werten gleich ignore case
    3. IN {1,2,3} filter → entspricht Wert aus einer Liste von Werten.
    4. filter → trifft zu, wenn der Vorname-Wert mit a beginnt.
    5. filter → Übereinstimmungen, wenn der FirstName-Wert mit li übereinstimmt.
    6. Prädikat mit Passport-Objekt Wir möchten Benutzer filtern, die Passnummer haben == ‚pass1‘
    7. Prädikat mit Todos-Objekt Wir möchten Benutzer filtern, die eine tdodo enthält Details == ‚Need ot create RxSwift blog‘

    Für erweiterte Abfragen wird dringend empfohlen, https://academy.realm.io/posts/nspredicate-cheatsheet/ dies NSPredicate cheatsheet

    Hinweis: Was Sie als „transiente (berechnete) Eigenschaften“ bezeichnen, bezeichnet Realm als „ignorierte Eigenschaften“. Dies sind Eigenschaften, die von Realm größtenteils ignoriert werden, sodass sie nicht in der DB-Datei gespeichert werden, außerhalb von Schreibtransaktionen mutiert werden können usw.Dies bedeutet jedoch auch, dass sie nicht von vielen Funktionen nicht ignorierter Eigenschaften wie Abfragen profitieren. (querying for Realm objects can only be done with non-computed, Realm-persisted properties)

    Figure 13

    As shown in Figure 14 we sorted results with the firstName property on User model

    Figure 14

    Live-Ergebnisse

    Letztes Thema zum Abrufen aus dem Realm-Bereich

    Realm-Ergebnismengen geben immer die neuesten Daten zurück. Daten in Ergebnissen sind nie veraltet. Dies bedeutet, dass Sie die Ergebnisse niemals von der Festplatte neu laden oder die In-Memory-Daten manuell aktualisieren müssen.

    Wie in Abbildung 15 gezeigt, haben wir den neuen Benutzer erhalten und nicht mit der realm.objects -Methode abgerufen. Wenn Sie aus dem Core Data-Hintergrund kommen, müssen Sie das Objekt erneut vom Stapel holen

    Das Lesen und Schreiben kann an verschiedenen Stellen im Projekt, in verschiedenen Threads, von verschiedenen Prozessen oder bei Verwendung der Realm-Plattform von überall auf der Welt erfolgen. Jede Klasse in der App kann sich auf die Geschäftslogik konzentrieren und den Begriff veralteter oder zwischengespeicherter Daten vergessen, da Realm-Objekte immer auf dem neuesten Stand sind.

    Abbildung 15

    Objekt auf Realm ändern

    Wie in Abbildung 16 gezeigt, ändern wir den Primärschlüssel und erhalten „Primärschlüssel kann nicht geändert werden, nachdem ein Objekt eingefügt wurde.“ ausnahme, da wir den Primärschlüssel nicht aktualisieren können. Von Realm Wenn der Primärschlüssel zu einem Realm hinzugefügt wird, kann der Primärschlüssel nicht geändert werden. Problemumgehung → Entfernen Sie das Objekt und fügen Sie es erneut ein oder sehen Sie sich diese Frage im Stackoverflow an

    16

    Wie in Abbildung 17 gezeigt, können Sie kein Objekt ändern, das aus einem Bereich außerhalb des Schreibtransaktionsblocks abgerufen wurde Wenn Sie versuchen, außerhalb dieses Bereichs zu ändern, erhalten Sie die Ausnahme „‚Beim Versuch, ein Objekt außerhalb einer Schreibtransaktion zu ändern, rufen Sie zuerst beginWriteTransaction in einer RLMRealm—Instanz auf.“

    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 19 default.realm file now has a updated firstName value of User

    Abbildung 18

    Abbildung 19

    Letztes Beispiel ist sehr interessant Wir haben folgende Aufgaben ausgeführt, um den Benutzer mit dem neuen Benutzer zu aktualisieren

    1. Wir erhalten den Benutzer mit seinem Primärschlüssel userId welches ist 1
    2. Erstellt neu User mit dem gleichen Primärschlüssel
    3. Bei einer Schreibtransaktion nennen wir add batch update-Methode Mit update = true wird der Benutzer mit Primärschlüssel = 1 aktualisiert. If update = false it will throw an exception since two objects can’t have same primary key as shown in Figure 20 and 21

    Figure 20

    Figure 21

    Delete Object From Realm

    Any objects currently wenn Sie mit den gelöschten verknüpfen, wird ihre Verknüpfungseigenschaft auf Null gesetzt. Wenn diese Objekte aus Listeneigenschaften verknüpft sind, werden sie aus den betreffenden Listen entfernt.

    As shown in Figure 22 and 23 we deleted User object having firstName == ‚ali new User‘

    Figure 22

    Figure 23

    As shown in Figure 24 we empty Realm database using deleteAll() method in realm-Objekt. Wie in Abbildung gezeigt realm.isEmpty gibt true zurück

    Abbildung 24

    Manchmal müssen Sie eine Art Hierarchie zwischen Realm-Objekten erstellen, genau wie Sie es mit Swift-Klassen gewohnt sind. Leider unterstützt Realm derzeit keine Objektvererbung. Problemumgehung: https://forum.realm.io/t/inheritance-with-realm-confusion/153

    Useful Links

    https://www.raywenderlich.com/9220-realm-tutorial-getting-started
    https://www.appcoda.com/realm-database-swift/

    https://realm.io/docs/swift/latest/#to-many-relationships
    https://realm.io/docs/swift/latest/#optional-properties

    https://academy.realm.io/posts/nspredicate-cheatsheet/

    https://academy.realm.io/posts/nspredicate-cheatsheet/

    Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht.