operacja CRUD za pomocą RealmSwift Część 1

w tej części omówimy:

  1. co to jest Realmswift
  2. Tworzenie złożonego modelu Realm
  3. dlaczego używamy @objc i dynamic w właściwościach
  4. To-One i to-Many Relationship w Realm
  5. Jak przechowywać niestandardowe enum w Realm
  6. co to jest RealmOptional i jak przechowywać Swift opcjonalna własność atomowa
  7. Jak Computed Property działa jako Transient Property w realm
  8. jak zrobić indeksowanie dla zwiększenia wydajności
  9. co to jest łączenie obiektu w Realm
  10. złożone zapytania Predykatowe
  11. operacja CRUD
  12. co to są wyniki na żywo w Realm
  13. rzeczy unikane, gdy Modyfikuj Obiekty Realm

Realm jest wieloplatformową mobilną bazą danych obiektów. Jest bardzo szybki, wydajny i łatwy w użyciu w porównaniu do danych podstawowych i Sqlite. Wykorzystuje swój mechanizm przechowywania do przechowywania obiektu jako JSON na dysku w porównaniu do podstawowych danych, które używają SQLite jako swojego zaplecza. Jest napisany w wieloplatformowym C++ , więc działa dokładnie tak samo na Androidzie, iOS, macOS lub dowolnej innej platformie.

RealmSwift

Większość Realm jest open-source, ale sekretem stojącym za platformą Realm jest Core dB engine napisany od podstaw w C++. RealmSwift jest owijką wokół Objective-C Realm framework i Objective-C Realm framework jest owijką wokół rdzenia silnika dB Realm.

wprowadzenie

w tym samouczku będziemy pracować nad tymi modelami, jak pokazano na rysunku 1

User → jest to model zawierający informacje o użytkowniku, w którymuserId jest to podstawowy. Ma również związek To-one z modelem paszportu i to-wiele relacji z zadaniami Todo. (Użytkownik może mieć tylko paszport i mieć wiele zadań todo)

Passport → jest to model zawierający informacje paszportowe użytkownika, a także posiada link zwrotny User obiektu.

Todo → jest to model zawierający zadania użytkownika, a także posiada link zwrotny User obiektu.

Rysunek 1ak pokazano na rysunku 2, stworzyliśmy model użytkownika i dodaliśmy kilka właściwości:

  1. najpierw dziedziczymy User klasa z Object co sprawia, że jest to UserRealm Object. Obiekty Realm są w zasadzie standardowym modelem danych, podobnie jak każdy inny standardowy model danych zdefiniowany w aplikacjach. Jedyną różnicą jest to, że są wspierani przez trwałość i zdolności Królestwa. Patrząc na wszystkieObject klasy Realm są w stanie wywnioskować twój schemat. Każdy model, który chcesz utrzymywać, musisz dziedziczyć z klasy Object.
  2. firstName przechowuje imię użytkownika jakoString. Ponieważ RealmSwift jest opakowaniem wokół typów frameworka Objective-C, takich jak String, Date i Data, są podklasami NSObject w Objective-C, więc można je również rozważyć w Swift. Oprócz tego @objc oznacza, że chcesz swój kod Swift (Klasa, metoda, właściwość itp.) być widocznym z Objective-C, podczas gdy dynamic oznacza, że chcesz użyć Objective-C Dynamic dispatch. Aby zrobić proste szybkie przechowywanie obiektów w serwerze database Realm używa funkcji dynamicznej wysyłki Objective-C do pracy pod maską
  3. userId Przechowuje identyfikator użytkownika, który działa jako klucz podstawowy. Jako klucz podstawowy można ustawić jedną z właściwości obiektu. Zazwyczaj właściwość, która jednoznacznie identyfikuje się, czyli jest głównym kandydatem na klucz podstawowy. Pomaga w szybkim wyszukiwaniu lub edycji obiektu w bazie danych. Jak pokazano na rysunku 2 wykonujemyuserId klucz podstawowy poprzez nadpisanieprimarykey funkcji statycznej. Domyślna implementacja tej metody zwraca nil. UwagauserId działa jako obiekt typu Objective C primitive int, ponieważ jest opakowaniem wokół Objective C Realm
  4. passport właściwość przechowuje informacje o paszporcie użytkownika, które są innym obiektem Realm. Stworzyliśmy relację to-One z Modelem paszportowym. To-jeden związek / obiekt , w którym jeden obiekt realm wskazuje na inny obiekt realm. Gdy tworzysz relację z innym obiektem Realm, jego właściwość musi być typu opcjonalnego. W passport variable pointer reference of Passport object will store
  5. privateUserType is the wrapper property of UserType since UserType is swift enum We can ’ t store directly on Realm. Wszystkie wartości case będą miały domyślnie przypisaną wartość surową pasującą do nazwy przypadku. Użyjesz tej wartości surowej, aby zachować opcje enum jako Int w Realm. Ale Klient uzyskuje dostęp do właściwości computed enum i pod maską enum raw value / Atomic value przechowuje w bazie danych, która nie jest widoczna dla klienta.
  6. właściwości String, nsdate i nsdata mogą być zadeklarowane jako opcjonalne lub nieobowiązkowe przy użyciu standardowej składni Swift.Opcjonalne typy liczbowe są deklarowane za pomocą RealmOptional. Ponieważ RealmSwift jest owijką wokół Objective C Realm i nie ma opcjonalnego Int w Objective C, dlatego Realm stworzył Typ RealmOptional dla tych scenariuszy. Wszystkie obiektywy typu C wymagają W Swift z opcjonalnym trzeba użyć RealmOptional . Notatka: właściwości RealmOptional nie mogą być deklarowane jako słowa kluczowe dynamic i @objc, ponieważ właściwości ogólne nie mogą być reprezentowane w Objective C runtime, który jest używany do dynamicznego wysyłania właściwości dynamicznych i powinien być zawsze deklarowany za pomocą let. Ponieważ jest klasą Realm, posiada wszystkie funkcje, które posiada obiekt Realm persist. Jak pokazano na rysunku 2 isEmailSubscriptionEnable deklarujemy jako RealmOptional Bool oznacza, że może być nil, którego użyliśmy z let, ponieważ jest to typ referencyjny i nie chcemy, aby jego adres zmieniał się w przyszłości.
  7. Jak pokazano na rysunku 2 Użytkownik może mieć wiele todos, które jest zbiorem obiektów Realm Todo . Lista jako klasa Realm do przechowywania kolekcji instancji obiektu Realm. Stworzyliśmy relację to-Many z Modelem Todo. To-wiele relacji, w której jeden obiekt realm wskazuje na zbiór obiektu realm. Jeśli użyjesz zwykłej tablicy Swift do przechowywania kolekcji obiektów Realm, otrzymasz wyjątek. Uwaga: podobnie jak lista RealmOptional nie może być zadeklarowana jako słowo kluczowe dynamic i @ objc, ponieważ jest to klasa Realm ze wszystkimi wbudowanymi funkcjami. Lista jest bardzo podobna do tablicy dla wbudowanych metod i dostępu do obiektów za pomocą indeksowanego subskryptora. Lista jak widzisz jest wpisana i wszystkie obiekty powinny być tego samego typu
  8. isUserHasTodos jest obliczoną właściwością swift i nie będzie przechowywana w bazie danych realm, która zwraca, jeśli użytkownik ma jakieś zadania do wykonania lub nie.
  9. w końcu tworzymyuserId IfirstName jako właściwości indeksowane. Poprzez nadpisanie metody statycznejindexedProperties udostępniamy tablicę właściwości w postaci String. Indeksujemy właściwości, aby poprawić czas dostępu podczas filtrowania lub odpytywania bazy danych

rysunek 2

model paszportu

jak pokazano na rysunku 3, stworzyliśmy model paszportu z kilkoma właściwościami

  1. passportNumberprzechowuje informacje o paszporcie iexpiryDate przechowuje datę ważności paszportu chcemy, aby te właściwości przechowywały dlatego my użyj @objc za pomocą dynamic słowa kluczowego, aby powiedzieć realm zrobić swoją magię pod maską
  2. stworzyliśmy passport właściwość na User model, co oznacza User object have their passport Object reference co zrobić, jeśli chcemy obiekt passport również wiedzieć, który Użytkownik ma ten paszport / mieć odniesienie do użytkownika powiązanego z tym paszportem. Backlinki stworzyliśmy za pomocą LinkingObjects, co oznacza, że stworzyliśmy ofUser właściwość w Passport, która zawiera odniesienia do wszystkich obiektów Użytkownika, które przypisują obiekt Passport w swojej właściwości passport. W podstawowych danych nazywa to odwrotną relacją. Jest to dynamiczna kolekcja informująca, kto łączy się z bieżącym obiektem.

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 .

Rysunek 4

zakończyliśmy tworzenie modelu / schematu i teraz nadszedł czas na rzeczywistą operację CRUD

Dodaj obiekt do Realm

najpierw wyczyścimy jakąś koncepcję, a następnie będziemy mogli łatwo dodać obiekt do Realm

jak pokazano na rysunku 5 zaczynamy od uzyskania instancji domyślnego Realminicjalizując go bez żadnych argumentów. Jedyny sposób na dostęp do bazy danych poprzez instancję realm. InstancjaRealm (zwana także „Realm”) reprezentuje bazę danych Realm.Domeny mogą być przechowywane na dysku (patrz init(path:)) lub w pamięci (patrz Configuration) zobaczymy w kolejnych częściach. Realm nie są bezpieczne dla wątków i nie mogą być współdzielone między wątkami ani kolejkami wysyłania. Musisz utworzyć nową instancję dla każdego wątku, w którym dostęp do serwera będzie możliwy.

jak pokazano na rysunku 5, ponieważ jest to świeża aplikacja i żaden obiekt nie został zapisany w bazie danych realm.isEmpty zwraca true, co oznacza, że baza danych jest pusta, jak wydrukowano na konsoli

rysunek 5

jak pokazano na rysunku 6 wykonaliśmy liczbę zadań

  1. otrzymujemy instancję Realmbaza danych
  2. utworzonaPassporti trzy zadania jako todos
  3. utworzył User obiekt i przypisał do niego passport i todos. Oprócz tej zainicjalizowanej opcjonalnej właściwości Realm, która jest isEmailSubscriptionEnable I Usertype enum with gold membership

Jak pokazano na rysunku 6 baza danych realm nadal pusta i odwrotna relacja/ łączenie obiektu też nie działa, ponieważ nie dodaliśmy tych obiektów do realm. Obiekty Realm (User, Passport, Todo)mogą być tworzone i używane jako obiekty niezarządzane (tj. nie są jeszcze dodawane do Realm), podobnie jak zwykłe obiekty Swift. Aby te obiekty były zarządzane przez Realm, musisz dodać je do Realm

rysunek 6

jak pokazano na rysunku 7 W końcu wstawiamy obiekt do bazy danych Realm. Wykonaliśmy kaskadowy wkład do DB.

Uwaga: wszystkie zmiany w obiekcie (dodanie, modyfikacja i usunięcie) muszą być wykonane w ramach transakcji zapisu.Operacje zapisu w serwerze Realm są synchroniczne i blokowane, a nie asynchroniczne. Jeśli wątek a rozpoczyna operację zapisu, to wątek B rozpoczyna operację zapisu na tym samym serwerze przed zakończeniem wątku a, wątek a musi zakończyć i zatwierdzić swoją transakcję przed zakończeniem operacji zapisu w wątku B. Operacje zapisu zawsze odświeżają się automatycznie, więc nie są tworzone żadne warunki wyścigu. Operacja zapisu może spowodować błąd, taki jak brak miejsca na dysku

  1. dodaliśmy użytkownika do Twojego Realm, a ponieważ odwołuje się do passport i todos, obiekty te są również dodawane do Realm.
  2. dodając niezarządzany obiekt do realm sprawiliśmy, że te obiekty zostały teraz zarządzane tak, jak pokazano w konsoli nasze linki zwrotne działają. Teraz passport może również uzyskać dostęp do obiektu użytkownika. Teraz nasza baza danych nie jest już pusta
  3. w końcu wstawiamy obiekt do bazy danych ponieważ wstawiamy obiekt musimy dodać do bloku transakcyjnego write i dodajemy do realm używając metody add na instancji Realm. Teraz, jeśli inny osobny obiekt z tym samym kluczem podstawowym Użytkownika o userId = 1 zostanie dodany jako oddzielny obiekt do serwera, zostanie wywołany wyjątek

rysunek 7

sprawdź obiekt fizycznie przechowuj

uruchamiając to polecenie na wyjściu debuggera, otrzymasz adres Pliku Realm, w którym przechowywane są Twoje dane

Rysunek 8

otwórz default.realm w Realm Studio
Realm Studio to nasze premierowe narzędzie programistyczne, zbudowane tak, abyś mógł łatwo zarządzać bazą danych realm i platformą Realm. Dzięki Realm Studio możesz otwierać i edytować lokalne i zsynchronizowane Serwery Realm oraz administrować dowolną instancją serwera obiektu Realm. Pobierz go teraz na Mac, Windows lub Linux.

rysunek 9

jak pokazano na rysunku 10 dane faktycznie przechowywane. Możesz się zastanawiaćArticle IPerson Klasa również tam, ponieważ w niektórych moich klasach projektu twórz modele osoba i artykuł. Po uruchomieniu aplikacji Realm introspektuje wszystkie klasy w aplikacji i frameworkach i odnajduje te klasy, które podklasa klasy obiektu Realm. Uważa listę tych klas za twój schemat danych, który będzie przechowywany na dysku lub w pamięci.

Rysunek 10

pobieranie obiektu z Realm

proces pobierania wszystkich rekordów użytkownika z Realm ma następujące zadania

  1. otrzymujemy instancję Realm database i może ona rzucić: NSErrorjeśli Realm nie mógł zostać zainicjowany. Domyślny realm jest tworzony, gdy wywołamy init() bez parametru
  2. wywołana metoda objects w bazie danych Realm, która zwróci wszystkie obiekty danego typu zapisane w Realm i zwróci wyniki ze wszystkimi obiektami, jak pokazano na rysunku 11
  3. Wydrukowany obiekt na konsoli, aby sprawdzić, czy dane tam są i łączenie obiektów działa poprawnie

rysunek 11

ściągnęliśmy użytkownika rekord z klucza podstawowego, który jest również indeksowaną właściwością, więc otrzymujemy opcjonalny obiekt User, ponieważ obiekt z tym kluczem podstawowym może nie istnieć. Klucz podstawowy może być Int lub String zaleca się użycie String. unikalnie identyfikuje określone obiekty w bazie danych Realm.Po ustawieniu wartości klucza podstawowego dla określonego obiektu nie można jej nigdy zmienić.

Rysunek 12

jak pokazano filtrowaliśmy za pomocą pewnego predykatu oto lista użytych operatorów

  1. filter → dopasowuje wartości równe
  2. filtruj niewrażliwe wielkości liter → dopasowuje wartości równe ignorowaniu wielkości liter
  3. w {1,2,3} filter → dopasowuje wartość z listy wartości.
  4. filter → pasuje, jeśli wartość firstName zaczyna się od a.
  5. filter → pasuje, jeśli wartość firstName łączy się z li.
  6. predykat z obiektem Passport chcemy filtrować użytkownika, który ma numer paszportu == 'pass1′
  7. predykat z obiektem Todos chcemy filtrować użytkownika, który ma dowolny tdodo zawiera szczegóły == 'Need OT create rxswift blog’

dla zaawansowanych zapytań zaleca się zobaczyćhttps://academy.realm.io/posts/nspredicate-cheatsheet/ to nspredicate Cheatsheet

uwaga: to, co określasz jako „właściwości przejściowe (obliczone)”, Realm odnosi się do „Właściwości ignorowane”. Są to właściwości, które są w większości ignorowane przez Realm, więc nie będą przechowywane w pliku db, mogą być mutowane poza transakcjami zapisu itp.Oznacza to jednak również, że nie korzystają one z wielu możliwości nie ignorowanych właściwości, takich jak zapytania. (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

wyniki na żywo

ostatni temat pobierania z sekcji Realm

zestawy wyników Realm zawsze zwracają najnowsze, aktualne dane. Dane w wynikach nigdy nie są przestarzałe. Oznacza to, że nigdy nie trzeba przeładowywać wyników z dysku lub w jakiś sposób ręcznie odświeżać danych w pamięci.

jak pokazano na rysunku 15 otrzymaliśmy nowego użytkownika i nie pobieraliśmy przy użyciu metody realm.objects zamiast tego nowo dodany obiekt jest prezentowany na zmiennej users . Jeśli pochodzisz z podstawowego tła danych, musisz ponownie pobrać obiekt ze stosu

Odczyt i zapis może się zdarzyć w różnych miejscach projektu, w różnych wątkach, z różnych procesów lub, podczas korzystania z platformy Realm, z dowolnego miejsca na świecie. Każda klasa w aplikacji może skupić się na logice biznesowej i zapomnieć o pojęciu przestarzałych lub buforowanych danych, ponieważ obiekty Realm są zawsze aktualne.

15

Modyfikuj obiekt na serwerze

jak pokazano na rysunku 16 modyfikujemy klucz podstawowy i otrzymujemy „klucz podstawowy nie może zostać zmieniony po włożeniu obiektu.”wyjątek, ponieważ nie możemy zaktualizować klucza podstawowego . Z dokumentu Realm klucz podstawowy jest dodawany do Realm, klucz podstawowy nie może być zmieniony. Obejście → Usuń i włóż ponownie obiekt lub zobacz to pytanie w stackoverflow

Rysunek 16

jak pokazano na rysunku 17 nie można modyfikować obiektu pobranego z obszaru poza blokiem transakcji zapisu jeśli spróbujesz zmodyfikować poza tym, otrzymasz wyjątek „’próba modyfikacji obiektu poza transakcją zapisu — wywołaj beginwritetransaction na instancji 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 19 default.realm file now has a updated firstName value of User

rysunek 18
19

ostatni przykład jest bardzo interesujący wykonaliśmy następujące zadania, aby zaktualizować użytkownika za pomocą Newuser

  1. otrzymujemy użytkownika z jego kluczem podstawowym userIdktóry jest 1
  2. utworzył nowyUserz tym samym kluczem podstawowym
  3. w transakcji zapisu wywołujemy add batch metoda update z update = true zaktualizuje Użytkownika posiadającego klucz podstawowy = 1 . 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 łączenie z usuniętymi ustawi ich Właściwość linking na nil. Jeśli obiekty te są połączone z dowolnymi właściwościami listy, są one usuwane z tych list.

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 obiekt realm. Jak pokazano na rysunku realm.isEmpty zwraca true

rysunek 24

czasami musisz zbudować jakąś hierarchię między obiektami Realm, tak jak zwykle robisz to z klasami SWIFT. Niestety Realm nie obsługuje obecnie dziedziczenia obiektów po wyjęciu z pudełka . Obejście: 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/

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.