Zastanawiam się, czy istnieje właściwy sposób na odzyskanie obiektu, biorąc pod uwagę jego klucz podstawowy w obszarze Realm dla Androida. Wiem, że metoda objectForPrimaryKey
istnieje w Swift, ale wydaje się, że nie ma takiego odpowiednika w Realm dla Androida. Naprawdę myślę, że robienie realm.where(EventInfo.class).equalTo("id", eventInfo.id).findFirst();
wygląda jak dużo odpadów (przynajmniej nie jest przyjazne dla nadgarstków). Czy brakuje mi jakiejś metody? Aktualnie używam Realm 1.0.1Właściwy sposób na uzyskanie obiektu Realm za pomocą klucza podstawowego w Androidzie Java
Odpowiedz
Czy brakuje mi jakiejś metody?
Nie. Jak wspomniałem, Beeender nie jest w tej chwili implementowany. Postęp/dyskusję można śledzić here.
Funkcja pomocnika mógłby wyglądać następująco
public class Cat extends RealmObject {
@PrimaryKey
private int id;
private String name;
public Cat getByPrimaryKey(Realm realm, int id) {
return realm.where(getClass()).equalTo("id", id).findFirst();
}
}
on metoda klasy specyficzne tutaj, ponieważ każda klasa może mieć inny podstawowy rodzaj klucza. Musisz przekazać do niej instancję realm, którą zarządzasz w klasie wywołującej.
Dlatego mam repozytorium Realm podobny do tego (co pisałem)
public class CalendarEventRepositoryImpl
extends LongRealmRepositoryImpl<CalendarEvent>
implements CalendarEventRepository {
public CalendarEventRepositoryImpl() {
super(CalendarEvent.class);
}
@Override
public Long getId(CalendarEvent calendarEvent) {
return calendarEvent.getId();
}
public void setId(CalendarEvent calendarEvent, Long id) {
calendarEvent.setId(id);
}
public String getIdFieldName() {
return CalendarEventFields.ID;
}
}
i dziedziczyć metody nazywanej findOne(realm, id);
jak
CalendarEvent event = calendarEventRepository.findOne(realm, id);
Ale tak, domyślnie jest to realm.where(CalendarEvent.class).equalTo("id", id).findFirst();
Miałem to na uwadze, ale potem zmieniłem odpowiedź, ponieważ nie jest to dane, że getId zwraca długi czas dla wszystkich modeli, jak sobie z tym radzisz? –
Rozciąga się od 'StringRealmRepositoryImpl' lub' NoIdRealmRepositoryImpl' w zależności od przypadku – EpicPandaForce
Nie podoba mi się wzór repozytorium, wolę bezpośrednio korzystać z ORM. Z mojego doświadczenia wynika, że repozytoriom jest więcej bólu niż jakiejkolwiek pomocy. ORM jest rodzajem repozytorium, ponieważ umożliwia dostęp i zapytanie do podstawowych danych bezpośrednio związanych z modelem obiektu. Martin Fowler zdefiniował repozytoria jako "obiekt, który pośredniczy między domeną a warstwami mapowania danych." To jest dokładnie to, co ORM dla IMHO :-) Więc prawdopodobnie będę podklasą samej Rzeczy i doda brakujące metody :-) – Loudenvier
Skończyło się tworzenie klasy pomocnika dla tego. Będę go używał, dopóki zespół Królestwa nie wdroży tych metod. Nazwałem klasę Find
(możesz zmienić jej nazwę tak, jak lubisz, ponieważ nazywanie rzeczy i unieważnianie pamięci podręcznej to the hardest things in computer science). Myślę, że lepiej jest użyć tego niż wywołać where().equalTo()
przekazując nazwę klucza podstawowego jako wartość ciągu. W ten sposób na pewno użyjesz właściwego pola klucza podstawowego. Oto kod:
import java.util.Hashtable;
import io.realm.Realm;
import io.realm.RealmModel;
import io.realm.RealmObjectSchema;
public final class Find {
// shared cache for primary keys
private static Hashtable<Class<? extends RealmModel>, String> primaryKeyMap = new Hashtable<>();
private static String getPrimaryKeyName(Realm realm, Class<? extends RealmModel> clazz) {
String primaryKey = primaryKeyMap.get(clazz);
if (primaryKey != null)
return primaryKey;
RealmObjectSchema schema = realm.getSchema().get(clazz.getSimpleName());
if (!schema.hasPrimaryKey())
return null;
primaryKey = schema.getPrimaryKey();
primaryKeyMap.put(clazz, primaryKey);
return primaryKey;
}
private static <E extends RealmModel, TKey> E findByKey(Realm realm, Class<E> clazz, TKey key) {
String primaryKey = getPrimaryKeyName(realm, clazz);
if (primaryKey == null)
return null;
if (key instanceof String)
return realm.where(clazz).equalTo(primaryKey, (String)key).findFirst();
else
return realm.where(clazz).equalTo(primaryKey, (Long)key).findFirst();
}
public static <E extends RealmModel> E byKey(Realm realm, Class<E> clazz, String key) {
return findByKey(realm, clazz, key);
}
public static <E extends RealmModel> E byKey(Realm realm, Class<E> clazz, Long key) {
return findByKey(realm, clazz, key);
}
}
Użycie jest bardzo proste:
// now you can write this
EventInfo eventInfo = Find.byKey(realm, EventInfo.class, eventInfoId);
// instead of this
EventInfo eventInfo = realm.where(EventInfo.class).equalTo("id", eventInfo.id).findFirst();
To będzie powrót null, jeśli nie ma klucz podstawowy dla danego obiektu lub jeśli obiekt nie został znaleziony. Zastanawiałem się nad wyrzuceniem wyjątku, jeśli nie było klucza głównego, ale zdecydowałem, że to przesada.
byłem bardzo smutny rodzajowych Java nie są tak wydajne jak C# rodzajowych, bo naprawdę chciałbym wywołać metodę w następujący sposób:
Find.byKey<EventInfo>(realm, eventInfoId);
I wierzcie mi próbowałem! Przeszukałem wszędzie, jak uzyskać zwrotną wartość typową dla metody. Kiedy okazało się niemożliwe, ponieważ Java kasuje metody rodzajowe, Próbowałem tworzenia klasy rodzajowy i zastosowanie:
(Class<T>)(ParameterizedType)getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
i wszystkie możliwe permutacje bezskutecznie! Więc zrezygnowałem ...
Uwaga: Zaimplementowałem tylko wersje String i Long o numerze Find.byKey
, ponieważ Realm akceptuje tylko dane String i Integral jako klucze podstawowe, a Long pozwala na sprawdzanie pól Byte i Integer (mam nadzieję !)
' (Class
z nowym Realm można uzyskać dostęp do klucza podstawowego tabeli, stosując schemat swojego DB w ten sposób:
private String load(Class realmClass) {
return mRealm.getSchema().get(realmClass.getSimpleName()).getPrimaryKey();
}
Nie jestem ekspertem w adnotacji, Próbowałam odczytaj wartość @PrimaryKey
w środowisku wykonawczym przez odbicie, używając getAnnotation()
w polach, ale wartości są zawsze null
, być może z powodu @Retention(RetentionPolicy.CLASS)
.
- 1. Tworzenie złożonego klucza podstawowego za pomocą struktury obiektu 4.1
- 2. Aktualizowanie/zmienianie klucza szyfrowania Realm
- 3. Utwórz widok za pomocą klucza podstawowego?
- 4. GROUP BY za pomocą klucza obcego lub klucza podstawowego?
- 5. Jak uzyskać wartość klucza podstawowego za pomocą Entity Framework Core
- 6. In View (CakePHP), właściwy sposób na uzyskanie aktualnego kontrolera?
- 7. Czy istnieje prosty sposób na uzyskanie rozmiaru obiektu java?
- 8. Jaki byłby właściwy sposób serializacji tego obiektu Java w Clojure?
- 9. Dziedzina Androida - przekazywanie obiektu Realm za pomocą intencji
- 10. Jak zmienić ograniczenie klucza podstawowego za pomocą składni SQL?
- 11. Orchard CMS: Właściwy sposób na uzyskanie wartości pola z widoku?
- 12. Swift Realm, załaduj wstępnie wypełnioną bazę danych we właściwy sposób?
- 13. Właściwy sposób na skonstruowanie mojego projektu C++ za pomocą cmake?
- 14. Tabele bez klucza podstawowego
- 15. właściwy sposób porównać obiektu w badanej jednostki
- 16. Czy istnieje sposób na uzyskanie "nazwanych" komórek za pomocą EPPlus?
- 17. Właściwy sposób buforowania danych z wywołania API za pomocą nodejs
- 18. Prawidłowy sposób na uzyskanie najbardziej negatywnego Double
- 19. Jak mogę pobrać wszystkie elementy z tabeli DynamoDB bez określania klucza podstawowego za pomocą java?
- 20. Najlepszy sposób na uzyskanie obiektu typu z łańcucha w .NET
- 21. IDataReader - Jakikolwiek sposób na uzyskanie całkowitych wierszy?
- 22. Dwa sposoby na uzyskanie wartości obiektu Point?
- 23. Właściwy sposób rejestrowania się w dzienniku zdarzeń za pomocą NLog
- 24. Błąd klucza podstawowego w jeden-na-jeden związek za pomocą Entity Framework
- 25. właściwy sposób za pomocą klas ES6 w nodejs projektu
- 26. Tworzenie klucza podstawowego na stole tymczasowym - kiedy?
- 27. Użyj klucza podstawowego złożonego jako klucza obcego
- 28. Zaktualizowany model Realm Swift
- 29. Jak sklonować obiektu sqlalchemy dB nowego klucza podstawowego
- 30. Clojure najlepszy sposób na uzyskanie wielu wątków?
Tak, to długa linia kodu :) Mamy otwarty problem dla niego https://github.com/realm/realm-java/issues/2166. Na razie myślę, że musisz użyć długiej linii lub utworzyć dla niej funkcję pomocnika. – beeender
@beeender Przyzwyczaiłem się do 'getObjectByKey (klucz T)' w wielu ORMach (nie że Realm to ORM, to więcej), więc pomyślałem, że może być coś już zrobionego w Królestwie. Może to nawet można zoptymalizować. Chciałbym również zasugerować metodę o nazwie .single() zamiast findFirst() dla przypadków, w których oczekiwany jest pojedynczy obiekt (prawdopodobnie rzucanie i wyjątek, jeśli znaleziono więcej niż jeden). Czy powinienem dodać tę sugestię w kwestiach realm-java? –
Loudenvier
Tak, proszę! Prowadzenie dyskusji w sprawie Githuba znacznie ułatwia nam śledzenie. Dzięki! – beeender