Der Chatroom bietet Funktionen zum Konvertieren zwischen primitiven und eingerahmten Typen Objektverweise zwischen Entitäten sind jedoch nicht zulässig. Dieses Dokument erklärt, wie Typkonverter verwendet werden und warum Room keine Objekte unterstützt Referenzen.
Typkonverter verwenden
Manchmal muss Ihre Anwendung einen benutzerdefinierten Datentyp in einer einzigen Datenbank speichern
Spalte. Sie unterstützen benutzerdefinierte Typen, indem Sie Typkonverter angeben. Dies sind
, die Room mitteilen, wie benutzerdefinierte Typen in und aus bekannten Typen konvertiert werden sollen,
Der Chatroom kann bestehen bleiben. Sie identifizieren Typkonverter mithilfe der Methode
@TypeConverter
-Anmerkung.
Angenommen, Sie müssen Instanzen von Date
in
in Ihrer Raumdatenbank. Der Raum weiß nicht, wie Date
-Objekte persistiert werden, daher benötigen Sie
zur Definition von Typkonvertern:
Kotlin
class Converters { @TypeConverter fun fromTimestamp(value: Long?): Date? { return value?.let { Date(it) } } @TypeConverter fun dateToTimestamp(date: Date?): Long? { return date?.time?.toLong() } }
Java
public class Converters { @TypeConverter public static Date fromTimestamp(Long value) { return value == null ? null : new Date(value); } @TypeConverter public static Long dateToTimestamp(Date date) { return date == null ? null : date.getTime(); } }
In diesem Beispiel werden zwei Methoden zum Typkonverter definiert: eine, die einen Date
konvertiert.
in ein Long
-Objekt und eines, das die umgekehrte Konvertierung von
Long
bis Date
. Da Room Long
-Objekte persistieren kann, kann es
diese Converter so, dass sie Date
-Objekte beibehalten.
Als Nächstes fügen Sie den @TypeConverters
hinzu.
an die AppDatabase
-Klasse an, damit Room Informationen zum Konverter erhalten.
von Ihnen definierter Klasse:
Kotlin
@Database(entities = [User::class], version = 1) @TypeConverters(Converters::class) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao }
Java
@Database(entities = {User.class}, version = 1) @TypeConverters({Converters.class}) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
Wenn diese Typkonverter definiert sind, können Sie Ihren benutzerdefinierten Typ in Ihrem Entitäten und DAOs genau wie primitive Typen verwenden:
Kotlin
@Entity data class User(private val birthday: Date?) @Dao interface UserDao { @Query("SELECT * FROM user WHERE birthday = :targetDate") fun findUsersBornOnDate(targetDate: Date): List<User> }
Java
@Entity public class User { private Date birthday; } @Dao public interface UserDao { @Query("SELECT * FROM user WHERE birthday = :targetDate") List<User> findUsersBornOnDate(Date targetDate); }
In diesem Beispiel kann der definierte Typkonverter überall verwendet werden,
hat AppDatabase
mit @TypeConverters
kommentiert. Sie können jedoch auch den Bereich
Nutzer, die eine Conversion zu bestimmten Entitäten oder DAOs ausführen, durch Anmerkungen zu @Entity
oder @Dao
Klassen mit @TypeConverters
.
Initialisierung des Steuerelementtypkonverters
Normalerweise übernimmt Room die Instanziierung von Typkonvertern für Sie. Sie können jedoch
Manchmal müssen Sie möglicherweise zusätzliche Abhängigkeiten an Ihren Typkonverter übergeben.
-Klassen, was bedeutet, dass Ihre App die Initialisierung direkt steuern muss.
Ihrer Typkonverter ein. Annotieren Sie in diesem Fall Ihre Konverterklasse mit
@ProvidedTypeConverter
:
Kotlin
@ProvidedTypeConverter class ExampleConverter { @TypeConverter fun StringToExample(string: String?): ExampleType? { ... } @TypeConverter fun ExampleToString(example: ExampleType?): String? { ... } }
Java
@ProvidedTypeConverter public class ExampleConverter { @TypeConverter public Example StringToExample(String string) { ... } @TypeConverter public String ExampleToString(Example example) { ... } }
Verwenden Sie dann neben der Deklaration der Konverterklasse in @TypeConverters
Folgendes:
die
RoomDatabase.Builder.addTypeConverter()
Methode zur Übergabe einer Instanz der Konverterklasse an die RoomDatabase
Builder:
Kotlin
val db = Room.databaseBuilder(...) .addTypeConverter(exampleConverterInstance) .build()
Java
AppDatabase db = Room.databaseBuilder(...) .addTypeConverter(exampleConverterInstance) .build();
Warum sind in „Room“ keine Objektverweise zulässig?
Wichtigste Erkenntnis: In diesem Chatroom sind Objektverweise zwischen Entitätsklassen nicht zulässig. Stattdessen müssen Sie explizit die Daten anfordern, die Ihre App benötigt.
Die Zuordnung von Beziehungen aus einer Datenbank zum jeweiligen Objektmodell ist eine gängige und funktioniert auf Server-Seite sehr gut. Auch wenn das Programm wenn darauf zugegriffen wird, funktioniert der Server dennoch gut.
Clientseitig ist diese Art von Lazy Loading jedoch nicht möglich, Sie erfolgt normalerweise im UI-Thread und die Abfrage von Informationen auf dem Laufwerk in der Benutzeroberfläche führt zu erheblichen Leistungsproblemen. Der UI-Thread enthält normalerweise etwa 16 ms, um das aktualisierte Layout einer Aktivität zu berechnen und zu zeichnen. nur 5 ms dauert, ist es trotzdem wahrscheinlich, dass Ihre App den Rahmen zeichnen, was zu wahrnehmbaren optischen Störungen führt. Die Abfrage könnte sogar noch mehr Zeit für den Abschluss, wenn eine separate Transaktion parallel läuft, oder Auf dem Gerät werden andere datenintensive Aufgaben ausgeführt. Wenn Sie keine ruft Ihre App jedoch mehr Daten ab, als sie benötigt, Konsumprobleme.
Objektrelationale Zuordnungen überlassen diese Entscheidung in der Regel den Entwickelnden, damit was für die Anwendungsfälle ihrer App am besten ist. Entwickler in der Regel das Modell zwischen der App und der Benutzeroberfläche zu teilen. Diese Lösung Das Modell lässt sich gut skalieren. Da sich die Benutzeroberfläche im Laufe der Zeit ändert, schafft Probleme, die für Entwickelnde schwer vorhersehbar und schwer zu beheben sind.
Stellen Sie sich beispielsweise eine Benutzeroberfläche vor, über die eine Liste von Book
-Objekten mit jedem Buch geladen wird.
mit einem Author
-Objekt. Sie könnten Ihre Abfragen anfangs
wird geladen, damit Instanzen von Book
den Autor abrufen. Der erste Abruf von
Das Feld author
fragt die Datenbank ab. Etwas später stellen Sie fest,
den Namen des Autors
auch auf der Benutzeroberfläche Ihrer App anzeigen. Sie können auf diese
wie im folgenden Code-Snippet gezeigt:
Kotlin
authorNameTextView.text = book.author.name
Java
authorNameTextView.setText(book.getAuthor().getName());
Diese scheinbar harmlose Änderung führt jedoch dazu, dass die Tabelle Author
abgefragt wird
im Hauptthread.
Wenn Sie die Autoreninformationen vorzeitig abfragen, wird es schwierig,
wie Daten geladen werden,
wenn Sie sie nicht mehr benötigen. Wenn die App beispielsweise
Die Benutzeroberfläche muss keine Informationen zu Author
mehr anzeigen, deine App wird effektiv geladen
die nicht mehr angezeigt werden, wodurch wertvollen Speicherplatz verschwendet wird. Der
Die Effizienz verschlechtert sich noch weiter, wenn die Klasse Author
auf eine andere Tabelle verweist.
z. B. Books
.
Wenn Sie in einem Chatroom auf mehrere Elemente gleichzeitig verweisen möchten, erstellen Sie stattdessen einen POJO, der alle Entitäten enthält, und schreiben Sie dann eine Abfrage, die die entsprechenden Tabellen. Dieses gut strukturierte Modell kombiniert mit der robusten Abfrage von Room Validierungsfunktionen, mit denen Ihre Anwendung beim Laden weniger Ressourcen verbraucht und so die Leistung und Nutzerfreundlichkeit Ihrer App verbessern.