You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Room框架中如何基于复合主键执行查询?

Room复合主键查询的正确实现方式

Room完全支持基于复合主键的查询,但你当前的写法存在问题——不能直接使用primaryKeys关键字作为查询条件,需要明确指定复合主键中的每个字段进行匹配。以下是两种正确的实现方案:

方案一:直接传入两个主键参数

直接将assetId和timestamp作为方法参数传入,在SQL语句中分别匹配这两个字段:

@Dao
interface MarketCapDao {
    // 你的实体类定义(已存在)
    @Entity(
        tableName = "market_cap",
        primaryKeys = ["assetId", "timestamp"]
    )
    data class MarketCapDataEntity(
        val assetId: String,
        val timestamp: Long,
        val price: Double
    )

    // 正确的复合主键查询方法
    @Query("SELECT * FROM market_cap WHERE assetId = :assetId AND timestamp = :timestamp")
    suspend fun getMarketCapByCompositeKey(assetId: String, timestamp: Long): MarketCapDataEntity?
}

这种方式简单直接,适合不需要封装主键的场景,同时能精准匹配唯一的复合主键记录(因为复合主键组合是唯一的,返回单个实体而非列表更合理)。

方案二:封装复合主键为对象传入

如果希望将复合主键封装成一个独立的对象,可以定义一个数据类作为复合键载体,在SQL语句中通过对象属性访问字段:

// 定义复合主键封装类
data class MarketCapCompositeKey(val assetId: String, val timestamp: Long)

@Dao
interface MarketCapDao {
    @Query("SELECT * FROM market_cap WHERE assetId = :key.assetId AND timestamp = :key.timestamp")
    suspend fun getMarketCapByCompositeKey(key: MarketCapCompositeKey): MarketCapDataEntity?
}

这种方式更符合面向对象的设计,当复合主键字段较多时,能简化方法参数的传递。

注意事项

  • 复合主键的组合在表中是唯一的,所以查询结果通常是单个实体,将返回值定义为MarketCapDataEntity?比List<MarketCapDataEntity>更贴合实际场景。
  • 确保SQL语句中的字段名和实体类中的属性名完全一致,Room默认使用属性名映射数据库字段(除非用@ColumnInfo指定了别名)。

内容的提问来源于stack exchange,提问作者Bitwise DEVS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 14:54:57