簡體   English   中英

討論如何使用嵌套集合為實體建模

[英]Room how to model Entity with nested collections

我嘗試重構一些代碼,並移動一些體系結構以使用體系結構組件中的Room Database。

我有這樣的對象,我經常使用它,從緩存中獲取它。 看起來像這樣:

public class LocationEvents {

private Map<NexoIdentifier, Date> mDeviceFirstSeenDates;

private ArrayDeque<LocationGeoEvent> mGeoEvents;
private ArrayDeque<LocationRSSIEvent> mRSSIEvents;
private Map<NexoIdentifier, ScoredLocationEvent> mHighestScores;

///Some methods

}

我想用這種結構對數據庫建模。 因此,將存在諸如LocationGeoEvent,LocationRSSIEvent,ScoredLocationEvent之類的實體。

他們看起來像這樣:

public class LocationGeoEvent {

private double mLongitude;
private double mLatitude;
private double mAccuracy;
private Date mTimestamp;
}

public class LocationRSSIEvent {

private int mRSSI;
private NexoIdentifier mNexoIdentifier;
private Date mTimestamp;
}

public class ScoredLocationEvent {

private float mScore;
private NexoIdentifier mNexoIdentifier;
private LocationRSSIEvent mLocationRSSIEvent;
private LocationGeoEvent mLocationGeoEvent;
private Date mScoreCalculatedTime;
private boolean mSent;
private boolean mPreviousSent;
}

NexoIdentifier是一個簡單的POJO:

class NexoIdentifier {
abstract val partialSerialID: String
abstract val id: String
abstract val countryAndManufacturer: String
}

那么如何使用Room建立關系? 甚至可以一次創建LocationEvent實體嗎? 因此,例如,我希望能夠使用嵌套在其中的所有此列表來獲取LocationEvent。 也許還有另一種方法可以做到這一點? 還不知道如何准確地將LocationEvents中的這兩個地圖(DeviceFirstSeenDates和HighestScores)建模為兩個相互關聯的單獨實體? 但是到底如何呢? 在這個示例中,我將非常感謝您的幫助,我真的很困

更新

@Entity(tableName = "location_events")
data class LocationEvents(
    @PrimaryKey(autoGenerate = true)
                 val id: Long = 0,
    @Embedded(prefix = "device") val mDeviceFirstSeenDates: Map<NexoIdentifier, Date> = HashMap(),
    @Embedded(prefix = "events") val mGeoEvents: ArrayDeque<LocationGeoEvent> = ArrayDeque(),
    val mRSSIEvents: ArrayDeque<LocationRSSIEvent> = ArrayDeque(),
    val mHighestScores: Map<NexoIdentifier, ScoredLocationEvent> = HashMap()
                 ) {
constructor() : this(0L, hashMapOf<NexoIdentifier, Date>(),
        ArrayDeque(), ArrayDeque(), hashMapOf<NexoIdentifier, ScoredLocationEvent>()
)

}

錯誤:錯誤:實體和Pojos必須具有可用的公共構造函數。 您可以有一個空的構造函數或一個其參數與字段匹配的構造函數(按名稱和類型)。

您可以使用嵌入式。 如果變量名相同,則要使用前綴。

例:

public class LocationEvents {

@Embedded(prefix="device") private Map<NexoIdentifier, Date> mDeviceFirstSeenDates;
@Embedded(prefix="events") private ArrayDeque<LocationGeoEvent> mGeoEvents;
private ArrayDeque<LocationRSSIEvent> mRSSIEvents;
private Map<NexoIdentifier, ScoredLocationEvent> mHighestScores;
}

或者您為此編寫一個Converter。

例:

public class DBConverters {
@TypeConverter
public static mapToString(Map<NexoIdentifier, Date value) {
    return value == null ? null : Gson.toJson(value);
}

@TypeConverter
public static Map<NexoIdentifier, Date> fromMap(String value) {
    return value == null ? null : Gson.fromJson(value, ...);
}
}

並在您的數據庫類中注釋您的Converter

@TypeConverters(DBConverters::class)
abstract class YourDb : RoomDatabase() { }

更新(代碼更新后):

該警告表示您至少需要一個可用的構造函數。 為了解決這個問題並仍然允許“數據”類,您需要使用ignore注釋,並注意您沒有任何可為空的值。

@Ignore constructor() : this(0L, hashMapOf<NexoIdentifier, Date>(),
        ArrayDeque(), ArrayDeque(), hashMapOf<NexoIdentifier, ScoredLocationEvent>()

這將確保Room使用您的類標題中使用的構造函數。

房間本身沒有“真實的” 關系 ,但是您可以創建一個包含關系的“虛擬類”。 Room支持ForeignKey,通過它可以定義關系被更新或刪除時的行為。 請注意,只能將嵌入式用於其他類。 如果有像HashMap這樣的未知類型,您將要編寫一個轉換器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM