【问题标题】:How to access object joined with SQL using Room on Android如何在 Android 上使用 Room 访问与 SQL 连接的对象
【发布时间】:2025-12-04 16:05:02
【问题描述】:

我想请教一下,在两个表上使用LEFT JOIN 后如何访问对象。我在外部文件 File.db 中定义了表,并将其加载到 Android 上的 Room 数据库中。我定义了两个表:

CREATE TABLE Example (
`id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`name`  TEXT NOT NULL,
`description`   TEXT,
`source_url`    TEXT
);

CREATE TABLE Example_dates (
`id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`example_id`    INTEGER NOT NULL,
`color` INTEGER NOT NULL,
`date_from` TEXT,
`date_to`   TEXT,
FOREIGN KEY(`example_id`) REFERENCES `Example`(`id`)
);

我的实体是:

@Entity(
  tableName = "Example"
)
data class Example constructor(
  @PrimaryKey @ColumnInfo(name = "id") var id: Int,
  @ColumnInfo(name = "name") var name: String,
  @ColumnInfo(name = "description") var description: String?,
  @ColumnInfo(name = "source_url") var sourceUrl: String?
)

@Entity(
  tableName = "Example_dates",
  foreignKeys = arrayOf(
    ForeignKey(entity = Example::class, parentColumns = ["id"], 
     childColumns = ["example_id"]))
)
data class Example_dates constructor(
  @PrimaryKey @ColumnInfo(name = "id") var id: Int,
  @ColumnInfo(name = "example_id") var exampleId: Int,
  @ColumnInfo(name = "color") var color: Int,
  @ColumnInfo(name = "date_from") var dateFrom: String?,
  @ColumnInfo(name = "date_to") var dateTo: String?
)

道对象:

@Dao
interface AnimalDao {
  @Query(
    "SELECT * FROM example_dates LEFT JOIN example ON example_dates.example_id = example.id")
  fun loadAll(): Cursor
}

我正在像这样构建数据库:

RoomAsset
  .databaseBuilder(context, AppDatabase::class.java, "File.db")
  .build()

有什么办法,如何以不同于 Cursor 的方式从 SQL 语句中获取合并数据?我尝试向data class Example@Ignore 注释的构造函数添加更多字段,但表中的差异出现错误 - “预期/找到”。还是基于游标的解决方案才是正确的实现方式?

谢谢。

【问题讨论】:

    标签: android database kotlin android-room android-architecture-components


    【解决方案1】:

    好的,正如官方文档所说https://developer.android.com/training/data-storage/room/accessing-data

    “强烈建议不要使用 Cursor API,因为它不能保证行是否存在或行包含什么值。”

    所以我尝试使用我需要的所有字段创建另一个 data class named ExampleDetail,并在 DAO 对象中返回 List 而不是 Cursor。

    谢谢。

    【讨论】: