2017-10-21 133 views
0

我尝试重构一些代码并移动多个体系结构以使用体系结构组件中的房间数据库。房间如何使用嵌套集合模型实体

我有这样的对象,我经常使用它,从缓存中获取它。 这里是什么样子:

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 
} 

那么,怎样才能让我用房间的关系?是否有可能将LocationEvent实体作为一次?所以例如我想能够获取所有嵌套在里面的所有列表的LocationEvent。或者也许有另一种方式来做到这一点? 也不知道如何在LocationEvents - DeviceFirstSeenDates和HighestScores中将这两个地图建模为两个独立的实体并与其他人建立关系?但究竟如何?我可能喜欢在这个例子中的帮助,我真的坚持

UPDATE

@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>() 
) 

}

Error:error: Entities and Pojos must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).

回答

2

您可以使用嵌入。如果你想使用前缀的变量名称相同。

例子:

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

或者你写一个转换器。 (在你的代码更新)

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

和注释你的转换器在你的DB类

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

更新:

警告意味着你至少需要一个可用构造函数。为了解决这个问题并且仍然允许“数据”类,你需要使用忽略注解,并注意你没有任何可为空的值。

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

这将确保Room使用您的类的标题中使用的构造函数。

房间本身没有“真实”relationships,但您可以创建一个“虚拟类”来保存关系。房间支持ForeignKey,它允许您在关系被更新或删除时定义行为。请注意,您只能使用嵌入的其他类。如果存在像你的HashMap那样的未知类型,你将会编写一个转换器。

+0

谢谢,但你能看看我的更新?我忘了提及我正在使用Kotlin。我有一个没有构造函数的错误,但它肯定存在 – Konrad

+0

,坚持。开始AS –