Sha*_*har 12 database android entity android-room
我有2个实体,硬币和CoinRevenue.
基本上,硬币以其他货币持有美元价格.
例如,带符号EUR的硬币,值为1.0356
@Entity(tableName = "coin")
data class Coin(
@field:PrimaryKey(autoGenerate = false)
var id: String = "",
var symbol: String = "",
var pricInUsd: Float = 0f)
Run Code Online (Sandbox Code Playgroud)
CoinRevenue是一个实体,我用它来保存用户拥有的特定硬币的硬币数量.例如,CoinRevenue与Coin Entity有关,EUR符号和金额为1000.
@Entity(tableName = "coinRevenue")
data class CoinRevenueNew(
@field:PrimaryKey(autoGenerate = true)
var id: Int = 0,
var coin: Coin? = null,
var amount: Float = 0f)
Run Code Online (Sandbox Code Playgroud)
现在我想从数据库中获取CoinRevenue并从数据库中获取更新的Coin.
例如,我用硬币保存了硬币(EUR,1.0253),而不是使用该硬币保存了CoinRevenue.
之后我用(EUR,2.522)更新了Coin我希望CoinRevenue中的Coin对象也会更新.
我知道@Embedded只是将内部objet字段作为列添加到同一个父对象.当我使用关系时,我必须使用List或Set.但我在CoinRevenue里总是有1枚硬币.
我的硬币DA:
@Query("select * from coin order by rank")
fun getAllCoins(): Flowable<List<CoinDB>>
@Query("select * from coin where rank = 1")
fun getFirstCoin(): Maybe<CoinDB>
@Query("select * from coin where favourite = 1 order by rank")
fun getAllFavouriteCoins(): Flowable<List<CoinDB>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertCoin(coinDB: CoinDB)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertCoins(coinsList: List<CoinDB>)
// -----------------
// CoinRevenue
// -----------------
@Query("select * from coinRevenue order by rank")
fun getAllCoinsRevenue(): Flowable<List<CoinRevenue>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertCoinRevenue(coinRevenue: CoinRevenue)
@Delete()
fun deleteCoinRevenue(coinRevenue: CoinRevenue)
Run Code Online (Sandbox Code Playgroud)
创造这个的最好方法是什么?
Sha*_*har 13
所以经过多次尝试,我已经设法让它发挥作用.
我更改了CoinRevenue对象以保存Coin id的外键
@Entity(tableName = "coinRevenue", foreignKeys = (arrayOf(ForeignKey(
entity = CoinDB::class,
onUpdate = ForeignKey.CASCADE,
parentColumns = arrayOf("coinId"),
childColumns = arrayOf("coinDbId"))))
)
data class CoinRevenue(
@ColumnInfo(name = "mid")
@PrimaryKey(autoGenerate = true)
var id: Long = 0L,
@ColumnInfo(name = "coinDbId")
var coinDbId: String? = null,
@ColumnInfo(name = "amount")
var amount: Double = 0.toDouble()
)
Run Code Online (Sandbox Code Playgroud)
我需要用两个对象创建一个POJO,如下所示:
class CoinRevenueWithCoin() : Parcelable {
@Embedded lateinit var coinDB: CoinDB
@Embedded lateinit var coinRevenue: CoinRevenue
}
Run Code Online (Sandbox Code Playgroud)
和这样的查询:
@Query("select * from coinRevenue, coin where coinRevenue.coinDbId = coin.coinId order by coin.rank")
fun getAllCoinsRevenueWithCoin(): Flowable<List<CoinRevenueWithCoin>>
Run Code Online (Sandbox Code Playgroud)
而已.
此外,此查询与任何其他常规对象查询一样,如果"coin"表或"coinRevenue"表中有任何更改,则会发出对象
您的解决方案有几个主要缺点。其中之一是表的列必须具有不同的名称。我建议不要应用@Relation,而不要使用@embededed。
@Entity(tableName = "coin")
data class Coin(
@field:PrimaryKey(autoGenerate = false)
var id: String = "",
var symbol: String = "",
var pricInUsd: Float = 0f)
@Entity(tableName = "coinRevenue", foreignKeys = (arrayOf(ForeignKey(
entity = CoinDB::class,
onUpdate = ForeignKey.CASCADE,
parentColumns = arrayOf("coinId"),
childColumns = arrayOf("coinDbId"))))
)
data class CoinRevenue(
@ColumnInfo(name = "mid")
@PrimaryKey(autoGenerate = true)
var id: Long = 0L,
@ColumnInfo(name = "coinDbId")
var coinDbId: String? = null,
@ColumnInfo(name = "amount")
var amount: Double = 0.toDouble()
)
Run Code Online (Sandbox Code Playgroud)
我不熟悉Kotlin,所以解决方案是使用Java
class CoinRevenueExt extends CoinRevenue {
@Relation(parentColumn = "coinDbId", entityColumn = "coinId" )
List<Coin> coins;
public Coin getCoin() {
return coins.get(0);
}
}
Run Code Online (Sandbox Code Playgroud)
道很简单
@Query("select * from coinRevenue")
public Flowable<List<CoinRevenueExt>> getAllCoinsRevenueWithCoin();
Run Code Online (Sandbox Code Playgroud)
很难说出你真正想要实现的目标是什么。另外,你的命名有点奇怪。看来币表确实包含了币种信息。coinRevenueNew 是一个分类帐条目或订单。如果您选择更容易理解的示例,更多的人会尝试阅读您的帖子。
另外,您想要解决的问题有点不清楚。- 您的问题是在数据库中建模吗?- 您的问题是您希望在货币变化时自动更新所有金额吗?- 您的问题是您希望在数据库更改时更新内存中的对象吗?- 您在 Room 中使用外键有问题吗?
其他人已经暗示了建模的第一个问题。您使用外键。有很多关于它的文章。
使用更容易理解的域名,您将有两个如下表:
create table currency (id integer primary key, exchange_rate float);
create table order (id integer primary key, int total, int currency_id, foreign key(currency_id) references currency(id));
Run Code Online (Sandbox Code Playgroud)
您将为每个创建 Room 实体。您将创建结合两者的第三个类(不要用 @Entity 标记它)。您可以在此处使用注释@Embedded或@Relation。该文档进一步解释了这一点:
https://developer.android.com/reference/androidx/room/Relation.html
如果更改货币,存储系统不会自动更新所有订单总计。如果您有一个“total_in_foreign_currency”字段和一个“total_in_master_currency”字段,数据库将不会为您重新计算。您必须手动迭代每一行并重新计算它。
内存中的数据对象不会神奇地更新。您必须跟踪检索数据的时间以及现在是否仍然如此。您可以使用 LiveData 在数据更改时收到通知(但它不会神奇地更新您的对象)。
| 归档时间: |
|
| 查看次数: |
8910 次 |
| 最近记录: |