Room'u kullanarak karmaşık verilere referans verme

Oda, temel ve kutulu türler arasında dönüştürme işlevi sağlar ancak varlıklar arasında nesne başvurularına izin vermez. Bu doküman Tür dönüştürücülerin nasıl kullanılacağını ve Odanın nesneyi neden desteklemediğini açıklar referanslar.

Tür dönüştürücüleri kullanma

Bazen uygulamanızın, özel bir veri türünü tek bir veritabanında depolaması gerekir sütununa girin. Özel türleri, dönüşüme olanak tanıyan tür dönüştürücüler sağlayarak desteklersiniz. Odaya özel türlerin bilinen türlere veya bu türlerden nasıl dönüştürüleceğini bildiren Oda kalıcı olabilir. Tür dönüştürücüleri tanımlamak için @TypeConverter ek açıklaması.

Şurada Date örneklerini kullanmaya devam etmeniz gerektiğini varsayalım: gidin. Oda, Date nesnelerini nasıl kalıcı hale getireceğini bilmiyor. Bu nedenle, şu yolu izleyin:

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();
  }
}

Bu örnekte, iki tür dönüştürme yöntemi tanımlanmaktadır: Date dönüştüren bir yöntem. Long nesnesine ve Long - Date. Oda, Long nesnelerini nasıl kalıcı olarak tutacağını bildiği için bu dönüştürücüleri Date nesnede kalıcı hale getirmek için kullanılır.

Daha sonra, @TypeConverters ekleyin. Ek açıklamayı AppDatabase sınıfına ekleyerek Odanın dönüştürücü hakkında bilgi sahibi olmasını sağlayın. sınıfları seçin:

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();
}

Bu tür dönüştürücüler tanımlandığında, varlıklarınızı ve DAO'larınızı, temel türleri kullandığınız gibi görürsünüz:

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);
}

Bu örnekte Oda, tanımlı tür dönüştürücüyü her yerde kullanabilir çünkü AppDatabase için @TypeConverters ile ek açıklama eklendi. Ancak kapsam türü @Entity veya @Dao açıklama ekleyerek, dönüşümü gerçekleştiren kullanıcıları belirli varlıklara veya DAO'lara @TypeConverters olan sınıflar.

Kontrol türü dönüştürücü başlatma

Normalde Oda, tür dönüştürücülerin örneklenmesini sizin için gerçekleştirir. Ancak, bazen tür dönüştürücünüze ek bağımlılıklar aktarmanız gerekebilir. Bu da uygulamanızın başlatma işlemini doğrudan kontrol etmesi için gerektiği anlamına gelir. seçenekleriniz bulunur. Bu durumda, dönüştürücü sınıfınıza @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) {
    ...
  }
}

Ardından, @TypeConverters uygulamasında dönüştürücü sınıfınızı bildirmeye ek olarak, "the" RoomDatabase.Builder.addTypeConverter() dönüştürücü sınıfınızın bir örneğini RoomDatabase oluşturucu:

Kotlin

val db = Room.databaseBuilder(...)
  .addTypeConverter(exampleConverterInstance)
  .build()

Java

AppDatabase db = Room.databaseBuilder(...)
  .addTypeConverter(exampleConverterInstance)
  .build();

Odanın neden nesne referanslarına izin vermediğini anlama

Temel çıkarım: Oda, öğe sınıfları arasında nesne referanslarına izin vermiyor. Bunun yerine uygulamanızın ihtiyacı olan verileri açıkça isteme.

Bir veritabanı ile ilişkileri ilgili nesne modeliyle eşlemek, sunucu tarafında çok iyi çalışıyor. Program yüklendiğinde bile daha iyi performans gösterirse sunucu yine de iyi performans gösterir.

Ancak istemci tarafında bu tür geç yükleme uygun değildir çünkü bu genellikle UI iş parçacığında gerçekleşir ve kullanıcı arayüzünde diskteki bilgileri sorgularken ileti dizisi, önemli performans sorunları oluşturur. UI iş parçacığı genellikle bir etkinliğin güncellenmiş düzenini hesaplamak ve çizmek için yaklaşık 16 ms. sorgusu sadece 5 ms. de olsa uygulamanızın muhtemelen Bu da göze çarpan görsel hatalara neden olabilir. Sorgu, paralel olarak gerçekleştirilen ayrı bir işlem varsa tamamlanması için daha fazla süre olup olmadığını kontrol edin. Tembel kullanmıyorsanız Ancak uygulamanız yüklendiğinden daha fazla veri getirerek bellekte tüketim sorunlarına yol açabilir.

Nesne ilişkisel eşlemeleri genellikle bu kararı geliştiricilere bırakır. uygulamasının kullanım alanı için en iyisini yapabilirler. Geliştiriciler genellikle modeli, uygulama ile kullanıcı arayüzü arasında paylaşmaya karar veriyor. Bu çözüm Çünkü kullanıcı arayüzü zamanla değiştikçe paylaşılan model geliştiricilerin öngörmesi ve hataları ayıklaması zor sorunlara yol açar.

Örneğin, her kitapla birlikte Book nesnelerin listesini yükleyen bir kullanıcı arayüzü düşünün Author nesnesi bulunuyor. Başlangıçta sorgularınızı tembel Book örneklerinin yazarı almak için yükleniyor. İlk alınan author alanı, veritabanını sorgular. Bir süre sonra, kendinize uygulamanızın kullanıcı arayüzünde yazar adını da görüntülemeniz gerekir. Bu bölümden aşağıdaki kod snippet'inde gösterildiği gibi kolayca bir ad verebilirsiniz:

Kotlin

authorNameTextView.text = book.author.name

Java

authorNameTextView.setText(book.getAuthor().getName());

Ancak, görünüşte masum olan bu değişiklik Author tablosunun sorgulanmasına neden olur ana ileti dizisinde yer alır.

Yazar bilgilerini önceden sorgularsanız, değiştirme işlemini verilerin nasıl yüklendiğini görebilirsiniz. Örneğin, uygulamanız Kullanıcı arayüzünün artık Author bilgilerini göstermesi gerekmiyor, uygulamanız etkili bir şekilde yükleniyor verileri kaybetmesine neden olabilir. Bu da değerli bellek alanının boşa gitmesine neden olur. Uygulamanızın Author sınıfı başka bir tabloya referans verirse verimlilik daha da düşer. (ör. Books).

Odayı kullanarak aynı anda birden çok varlığa referans vermek için bunun yerine bir Her varlığı içeren POJO'ya dokunup ardından ilgili varlıkla birleştiren bir sorgu yazın tablolarında anlatacağım. Odanın güçlü sorgusu ile birlikte, iyi yapılandırılmış bu model Bu, uygulamanızın yükleme sırasında daha az kaynak tüketmesini sağlar Böylece uygulamanızın performansını ve kullanıcı deneyimini iyileştirebilirsiniz.